代码之家  ›  专栏  ›  技术社区  ›  Alex

java中未选中的赋值

  •  2
  • Alex  · 技术社区  · 7 年前

    我使用以下代码在一个n维列表中查找唯一对象的一维列表(归功于StackOverflow上的某个人刚才的方法):

    public static <T> List<T> getUniqueObjectsInArray(List<T> array) {
        Integer dimension = getDimensions(array);
        return getUniqueObjectsInArray(array, dimension);
    }
    
    private static <T> List<T> getUniqueObjectsInArray(List<T> list0, Integer dimension) {
        List<T> list1 = new ArrayList<T>();
        return getUniqueObjectsInArray(list0, list1, dimension);
    }
    
    private static <T> List<T> getUniqueObjectsInArray(List<T> list0, List<T> list1, int dimension) {
        if (dimension < 1) return null;
        if (dimension == 1) {
            for (T listItem : list0) {
                if (!list1.contains(listItem)) list1.add(listItem);
            }
            return list1;
        } else {
            for (Object listItem : list0) {
                getUniqueObjectsInArray((List)listItem, list1, dimension - 1);
            }
        }
        return list1;
    }
    

    它可以工作,但我在施放时仍收到“未经检查的任务”警告 listitem List 在以下行中

     getUniqueObjectsInArray((List)listItem, list1, dimension - 1);
    

    现在我知道我可以添加 @SuppressWarnings("unchecked") 它会隐藏警告。但是,在没有这种警告的情况下,有没有一种根本不同的做法?如果这个警告真的存在,到底有什么关系呢?基本良好的代码是否仍能包含警告?

    4 回复  |  直到 7 年前
        1
  •  1
  •   Ralf Kleberhoff    7 年前

    我看不到消除该警告的方法,因为您必须非常小心地声明和使用正确的泛型数组类型。所以也许你决定忽略这个警告。。。

    • 具有T型元素的一维数组由 List<T> 公告
    • 二维数组是一个列表,包含元素列表,因此 List<List<T>> .
    • 三维数组是一个列表,包含列表元素的列表,因此 List<List<List<T>>> .
    • 等等

    搜索的核心是递归 getUniqueObjectsInArray(...) 方法要消除警告,您必须确保使用例如。 List<List<List<String>>> 使用生成递归(内部)调用 List<List<String>> ,并且维度比之前小1,因此第一次尝试如下:

    public static <T,E> getUniqueObjectsInArray(List<T> array, List<E> results, int dimension) {
        //...
        for (T listItem : array) {
            getUniqueObjectsInArray(listItem, results, dimension - 1);
        }
    }
    

    这也行不通,因为编译器不允许您进行递归调用,因为他无法确保listItem是一个列表。让我们试着通过以下方式告诉他:

    public static <T,E> getUniqueObjectsInArray(List<List<T>> array, List<E> results, int dimension) {
        //...
        for (List<T> listItem : array) {
            getUniqueObjectsInArray(listItem, results, dimension - 1);
        }
    }
    

    现在他知道这是一个列表,但现在这还不够,因为现在你需要一个 List<List<whatever>> 用于呼叫 getUniqueObjectsInArray(…) .

    你看,如果可能的话,尝试做正确的泛型声明以使编译器不发出警告变得非常复杂。老实说,我没有办法避免这些警告,所以不要花太多时间,添加@SuppressWarnings(“未选中”)。

        2
  •  0
  •   marknorkin    7 年前

    嗯,我看不到摆脱这个警告的方法,因为 您执行向下投射 Object List .

    在您的情况下,列表中的项目 可以是某个对象或列表 ,并且您没有泛型支持或其他可以描述这一事实的语言构造。

    所以,正如我在某个时候看到的,你需要执行铸造操作。

    但不同的是,你现在拥有的东西并不安全:你到底如何确保

    for (Object listItem : list0) {
        getUniqueObjectsInArray((List)listItem, list1, dimension - 1);
    }
    

    那个 listItem 是列表的子类型吗?

    您可以尝试绑定泛型类型和/或执行 instance of 检查以确保铸件的正确性。

        3
  •  0
  •   matt    7 年前

    您正在隐式转换列表中的所有项目。

    static <T> T findAnItem(List<T> items){
    
        return items.get(0);
    }
    
        List<Integer> ints = new ArrayList<>();
        ints.add(0);
        Object a = ints;
        System.out.println(findAnItem((List<?>)a));
    

    此示例将在没有警告的情况下编译,因为我没有将列表中的对象强制转换为Object之外的任何对象。如果我切换 ? Integer ,然后我得到一个警告。

        4
  •  -1
  •   Joe    7 年前

    这是因为您正在将对象“listItem”强制转换为没有泛型类型参数的“List”。

    要消除这种情况,只需将泛型类型参数添加到强制转换中,就可以消除警告

    (List<T>) listItem