Java 如何创建一个集合的数组?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2992615/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 15:21:29  来源:igfitidea点击:

How to create an array of a collection?

java

提问by Murali

Possible Duplicate:
What’s the reason I can’t create generic array types in Java?

可能的重复:
我无法在 Java 中创建通用数组类型的原因是什么?

HashSet<Integer>[] rows = new HashSet<Integer>[9];

gives me a compilation error: generic array creation.

给了我一个编译错误:通用数组创建。

采纳答案by Hyman

The simple answer: do not mix arrays with generics!

简单的答案:不要将数组与泛型混合使用!

Use a list of hashsets:

使用哈希集列表:

ArrayList<HashSet<Integer>> rows = new ArrayList<HashSet<Integer>>();

The problem here is that Java specification doesn't allow you to declare an array of generics object.

这里的问题是 Java 规范不允许您声明泛型对象数组。

A workaround of it is to use the wildcard, but you will lose the type-safety:

一种解决方法是使用通配符,但您将失去类型安全性:

HashSet<?>[] rows = new HashSet<?>[9];

for (int i = 0; i < rows.length; ++i)
    rows[i] = new HashSet<Integer>();

This, in your case, won't create problems when you are going to check if an item is contained: you can easily do rows[0].contains(4)but when adding new content you will be forced to cast the row to the right type and suppress the warning of unchecked cast itself:

在您的情况下,当您要检查是否包含项目时,这不会产生问题:您可以轻松做到,rows[0].contains(4)但是在添加新内容时,您将被迫将行强制转换为正确的类型并取消未选中的警告演员本身:

((HashSet<Integer>)rows[0]).add(4);

A side note: if you feel pioneer just download the Trove Collectionsframework that has a not-generics, highly optimized version of an integer hashsetmade to work with primitive type, I'm talking about the TIntHashSetclass: it will solve your problem and you'll end up having faster code.

旁注:如果您觉得先驱者只需下载Trove Collections框架,该框架具有非泛型、高度优化的整数哈希集版本,可用于原始类型,我说的是TIntHashSet类:它将解决您的问题,而您最终会有更快的代码。

回答by Justin

You can declare the generic on the type declaration, but not when you actually allocate the object. Not sure the exact reason, perhaps to re-enforce the concept that some generics information is not preserved at compile time.

您可以在类型声明中声明泛型,但不能在实际分配对象时声明。不确定确切的原因,也许是为了加强在编译时不保留某些泛型信息的概念。

Set<Integer> rows[] = new HashSet[3];
for (int i = 0; i < rows.length; i++) {
 rows[i] = new HashSet<Integer>();
}

回答by Powerlord

To quote Effective Java Second edition by Joshua Bloch, page 119

引用 Joshua Bloch 的 Effective Java 第二版,第 119 页

Because of these fundamental differences, arrays and generics do not mix well. For example, it is illegal to create an array of a generic type, a parameterized type, or a type parameter. None of these array creation expressions are legal: new List<E>[], new List<String>[], new E[]. All will result in generic array creationerrors at compile time.

Why is it illegal to create a generic array? Because it isn't typesafe. If it were legal, casts generated by the compiler in an otherwise correct program could fail at runtime with a ClassCastException. This would violate the fundamental guarantee provided by the generic type system.

由于这些根本差异,数组和泛型不能很好地混合。例如,创建泛型类型、参数化类型或类型参数的数组是非法的。这些数组创建表达式都不合法:new List<E>[], new List<String>[], new E[]. 所有这些都会在编译时导致通用数组创建错误。

为什么创建泛型数组是非法的?因为它不是类型安全的。如果它是合法的,编译器在其他正确的程序中生成的强制转换可能会在运行时失败并带有 ClassCastException. 这将违反泛型类型系统提供的基本保证。

(I omitted the part that explains Generic type erasure)

(我省略了解释通用类型擦除的部分)

The Generics chapter of this book is available as a PDF.

本书的泛型章节以 PDF 格式提供

回答by corsiKa

Any time you're chaining generics or nesting data structures like this, it's time to take a step back and think about what you're really trying to do.

每当您像这样链接泛型或嵌套数据结构时,是时候退后一步思考您真正想要做什么了。

Would this be better if it were encapsulated in a wrapper class? It will probably make things less complex later. A week from now when you have to debug something in your array of hashsets of arraylists of arrays of some simple datatype because you thought you'd just keep wrapping them, you'll be sorry.

如果将其封装在包装类中会更好吗?它可能会使以后的事情变得不那么复杂。一周后,当您必须调试某些简单数据类型的数组的数组列表的哈希集数组中的某些内容时,因为您认为您只是继续包装它们,您会感到抱歉。

-edit: arrays are illegal? Point noted. I still feel the argument here stands.

-编辑:数组是非法的?点指出。我仍然觉得这里的论点成立。

You're using Java; don't be afraid to make some extra classes.

您正在使用 Java;不要害怕做一些额外的课程。

public class MyIntegers {
    private HashSet<Integer> theIntegers;

    // wrap methods
    public boolean add(Integer i) { return theIntegers.add(i); }
    public boolean contains(Integer i)...
    public boolean remove(Integer i)...

}

// later...
public static void main(String[] args) {
    MyIntegers[] rows = new MyIntegers[NUM_ROWS];
}