在 .NET 中,数组和列表都将 Enumerable 作为祖先,因此接受 Enumerable 作为参数的方法可以同时接收数组和列表作为其参数。我想知道Java中是否有类似的东西?
6 回答
不,Java 中没有等价物。我一般会建议你设计 API 方法来接收List<T>
,Collection<T>
或Iterable<T>
. 虽然这些排除了直接使用数组调用方法,但您可以非常轻松地使用Arrays.asList
. 对于调用者来说,这比将数组指定为方法参数更灵活,后者强制执行单个实现。
我同意这并不理想。
请注意,在 .NET 中,一维数组不只是实现IEnumerable<T>
——它们也实现IList<T>
了。
它们没有共同的祖先,但是,有一些方法可以根据需要在两种类型之间进行转换 -
所以你可以提供一个重载的方法来转换为一个常见的类型——即
public void doAll(MyType[] array) {
doAll(Arrays.asList(array));
}
public void doAll(List<MyType> list) {
//... process List here.
}
Java 中的 Array 和 List 不共享 java.lang.Object 以外的共同祖先。
两者都可以使用 foreach 循环访问,如下所示:
String [] array = new String [] { "foo", "bar", "baz", };
List<String> list = Arrays.asList( "x", "y", "z");
for (String s : array)
System.out.println(s);
for (String s : list)
System.out.println(s);
基本上,数组有一个隐式类型,它是对象的子类。请参阅JLS 中的数组:
public static void main(String[] args) {
int[] ia = new int[3];
System.out.println(ia.getClass());
System.out.println(ia.getClass().getSuperclass());
}
> class [I
> class java.lang.Object
当我们考虑协变/逆变时,处理数组和列表的方式也不相同。
List<Object> l = new ArrayList<String>(); // complain
Object[] l2 = new String[1]; // ok
l2[0] = 4; // throw ArrayStoreException.
如果我们考虑泛型,情况会变得更糟,但这是另一个话题。总而言之,我不知道这种设计的基本原理,但我们需要忍受它。
两者都源自java.lang.Object
. 但是,这与收藏无关,我认为这就是您要寻找的。
Iterable<T>
是 Java 的等价物IEnumerable<T>
。所有/大多数集合都实现了这个接口(包括ArrayList
和数组),所以是的。但它不是“祖先”(它也不在 .NET 中),而是一个通用接口。