从集合中按索引获取值的最佳方法

57

如何通过索引从 java.util.Collection 获取最佳价值?

11个回答

60

你不应该这样做。一个Collection没有专门谈论索引,因为对于特定的集合可能没有意义。例如,List暗示某种形式的排序,而Set则不是。

Collection<String> myCollection = new HashSet<String>();
myCollection.add("Hello");
myCollection.add("World");

for (String elem : myCollection) {
    System.out.println("elem = " + elem);
}

System.out.println("myCollection.toArray()[0] = " + myCollection.toArray()[0]);

会给我:

elem = World
elem = Hello
myCollection.toArray()[0] = World

虽然:

myCollection = new ArrayList<String>();
myCollection.add("Hello");
myCollection.add("World");

for (String elem : myCollection) {
    System.out.println("elem = " + elem);
}

System.out.println("myCollection.toArray()[0] = " + myCollection.toArray()[0]);

给了我:

elem = Hello
elem = World
myCollection.toArray()[0] = Hello

为什么你要这样做?难道你不能只遍历整个集合吗?


嗨@butterchicken,我的情况是我使用了一个LinkedHashMap,在其中获取键集(它是一个Set<String>)。我发现这篇帖子:https://dev59.com/YXA85IYBdhLWcg3wJf8Z 表明该集合内的顺序是有保证的。那么我是否仍然不应该遍历它? - jobbert
1
@jobbert 你可以绝对地迭代它。在这种情况下,你会得到一个Set,因为这是Map接口的契约。 - butterchicken

27

我同意Matthew Flaschen的答案,只想展示一些选项,以防您无法切换到List(因为库返回了一个Collection):

List list = new ArrayList(theCollection);
list.get(5);
或者
Object[] list2 = theCollection.toArray();
doSomethingWith(list[2]);

如果您知道泛型是什么,我也可以提供相关示例。

编辑:原始集合的意图和语义是另一个问题。


1
如果库函数返回一个 Collection,则我认为您无法保证该 collection 中元素的顺序。大概库调用返回一个 Collection,正是因为它不希望您做出这些假设? - butterchicken
好的观点。OP没有分享关于他正在使用哪种库的足够信息。有些库返回Collection只是因为开发人员读到了一种最佳实践,即返回某个超级接口而不是具体实现。如果库从未打算允许除循环结果之外的任何其他操作(例如在AXIOM中),则可以仅返回Iterable。 - akarnokd
@akarnokd 关于 Collection 接口的问题。没有 "get(idx)" 方法。 - Meow Meow

19

通常情况下,没有好的方法,因为Collection不能保证有固定的索引。是的,您可以通过迭代它们来实现,这也是toArray(和其他函数)的工作方式。但是迭代顺序不一定是固定的,如果您正在尝试对一般的Collection进行索引,那么您可能在做错什么。更明智的做法是索引到一个List


11

6
你必须将你的集合包装在一个列表中(new ArrayList(c))或使用c.toArray(),因为集合没有"索引"或"顺序"的概念。

3

使用函数将集合转换为数组

Object[] toArray(Object[] a) 

1

你绝对需要一个列表

List接口提供了四种方法来访问列表元素的位置(索引)。列表(如Java数组)从零开始。

此外

请注意,这些操作可能会在某些实现中(例如LinkedList类)以与索引值成比例的时间执行。因此,如果调用者不知道实现方式,则通常优先使用迭代列表中的元素而不是通过索引进行访问。

如果您需要索引以修改集合,则应注意List提供了一个特殊的ListIterator,允许您获取索引:

List<String> names = Arrays.asList("Davide", "Francesco", "Angelocola");
ListIterator<String> i = names.listIterator();

while (i.hasNext()) {
    System.out.format("[%d] %s\n", i.nextIndex(), i.next());
}

1

如果只是想在更新时将集合转换为列表也很方便。但是,如果您正在初始化,以下方法就足够了:

for(String i : collectionlist){
    arraylist.add(i);
    whateverIntID = arraylist.indexOf(i);
}

保持开放的心态。


0

使用 for each 循环...

ArrayList<Character> al = new ArrayList<>();    
String input="hello";

for (int i = 0; i < input.length(); i++){
    al.add(input.charAt(i));
}

for (Character ch : al) {               
    System.Out.println(ch);             
}

0
如果你的`Collection`是一个`List`,只需将其强制转换为`List`并调用`get(final int index)`。否则,考虑在有序集合中查找第n个元素可能会更有意义,例如如果它是一个尊重插入顺序的`LinkedHashSet`(请记住,有可能创建这样一个不尊重插入顺序的实例),您可以使用`Collection.stream().skip(index).limit(1).findFirst().orElse(null)`。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接