如果我有一个集合,例如Collection<String> strs
,我怎样才能取出第一个项目?我可以打电话给 an Iterator
,先拿走它next()
,然后扔掉Iterator
。有没有更浪费的方法呢?
14 回答
看起来这是最好的方法:
String first = strs.iterator().next();
好问题……起初,这似乎是对Collection
界面的疏忽。
请注意,“first”并不总是返回您放入集合中的第一件事,并且可能仅对有序集合有意义。也许这就是为什么没有get(item)
调用的原因,因为不一定会保留订单。
虽然它可能看起来有点浪费,但它可能没有你想象的那么糟糕。实际上只是包含索引信息到集合中,而Iterator
不是通常整个集合的副本。调用此方法确实会实例化Iterator
对象,但这确实是唯一的开销(不像复制所有元素)。
例如,查看ArrayList<String>.iterator()
方法返回的类型,我们看到它是ArrayList::Itr
. 这是一个内部类,它只直接访问列表的元素,而不是复制它们。
请务必检查返回,iterator()
因为它可能为空或null
取决于实现。
Iterables.get(yourC, indexYouWant)
因为真的,如果你使用收藏,你应该使用谷歌收藏。
在 Java 8 中:
Optional<String> firstElement = collection.stream().findFirst();
对于旧版本的 java,Guava Iterables中有一个 getFirst 方法:
Iterables.getFirst(iterable, defaultValue)
a 中没有“第一个”项目这样的东西,Collection
因为它只是一个集合。
从 Java 文档的Collection.iterator()方法:
无法保证返回元素的顺序...
所以你不能。
如果您使用其他接口,例如List,您可以执行以下操作:
String first = strs.get(0);
但是直接从一个集合中这是不可能的。
听起来您的 Collection 想要像 List 一样,所以我建议:
List<String> myList = new ArrayList<String>();
...
String first = myList.get(0);
功能方式:
public static <T> Optional<T> findFirst(List<T> result) {
return Optional.ofNullable(result)
.map(List::stream)
.flatMap(Stream::findFirst);
}
上面的代码片段保留从 NullPointerException 和 IndexOutOfBoundsException
在 Java 8 中,您可以使用许多运算符,例如limit
/**
* Operator that limit the total number of items emitted through the pipeline
* Shall print
* [1]
* @throws InterruptedException
*/
@Test
public void limitStream() throws InterruptedException {
List<Integer> list = Arrays.asList(1, 2, 3, 1, 4, 2, 3)
.stream()
.limit(1)
.collect(toList());
System.out.println(list);
}
Guava 提供了一个onlyElement
Collector
,但仅当您希望集合只有一个元素时才使用它。
Collection<String> stringCollection = ...;
String string = collection.stream().collect(MoreCollectors.onlyElement())
如果您不确定有多少元素,请使用findFirst
.
Optional<String> optionalString = collection.stream().findFirst();
你可以做一个铸造。例如,如果存在一个具有此定义的方法,并且您知道此方法返回一个 List:
Collection<String> getStrings();
在调用它之后,你需要第一个元素,你可以这样做:
List<String> listString = (List) getStrings();
String firstElement = (listString.isEmpty() ? null : listString.get(0));
如果您知道集合是一个队列,那么您可以将集合转换为队列并轻松获取它。
您可以使用几种结构来获取订单,但您需要对其进行强制转换。
这完全取决于您使用的是哪个实现,是 arraylist 链表,还是 set 的其他实现。
如果设置了,那么您可以直接获取第一个元素,它们可以对集合进行特技循环,创建一个值为 1 的变量,并在标志值为 1 时获取值,然后打破该循环。
如果它是列表的实现,那么通过定义索引号很容易。
我用这个:
strs.isEmpty() ? "" : strs.iterator().next();
如果您使用的是 Apache Commons Collections 4,则有一种IterableUtils.first
方法。它包含对List
s 的优化,并且使用起来很整洁。它与 Guava 方法非常相似。代码看起来像
String firstStr = IterableUtils.first(strs);
你可以这样做:
String strz[] = strs.toArray(String[strs.size()]);
String theFirstOne = strz[0];
Collection 的 javadoc 对数组元素的顺序给出了以下警告:
如果此集合对其迭代器返回其元素的顺序做出任何保证,则此方法必须以相同的顺序返回元素。