Search Java library方法来查找集合中的项,并检查是否恰好有一个匹配项

Search Java library方法来查找集合中的项,并检查是否恰好有一个匹配项,search,collections,java,iterable,Search,Collections,Java,Iterable,是否有公共Java库提供了在有限集合中查找元素的方法,并确保只有一个匹配项 例如,如果没有找到任何内容,该方法可以返回null,如果找到多个元素,则抛出异常 目前我使用自己的实现(见下文),但我不希望用这些实用程序方法污染业务代码(即使在单独的实用程序包中提取) 我也不希望重复集合一次的开销,或者过滤集合和查看结果长度的开销 另外,我当前的解决方案(有效,但将用库方法替换): public static T getSingleMatch(Iterable lookIn,com.google.co

是否有公共Java库提供了在有限集合中查找元素的方法,并确保只有一个匹配项

例如,如果没有找到任何内容,该方法可以返回
null
,如果找到多个元素,则抛出异常

目前我使用自己的实现(见下文),但我不希望用这些实用程序方法污染业务代码(即使在单独的实用程序包中提取)

我也不希望重复集合一次的开销,或者过滤集合和查看结果长度的开销

另外,我当前的解决方案(有效,但将用库方法替换):

public static T getSingleMatch(Iterable lookIn,com.google.common.base.Predicate

If
index!=-1
表示没有此类项。如果下一个If语句的计算结果不为true,则表示至少有2项。您可以将其重新构造为抛出异常、返回null或返回索引或项。我相信您知道如何根据您的问题执行此操作。

一个选项是将这两个想法分成两部分hods,这样每个方法都做一件事,然后组合调用

  • 一种延迟过滤的方法,返回一系列匹配结果
  • 一种从序列返回项的方法,要求它是唯一的项
这两方面都有:

  • 懒散地过滤
  • 返回序列的唯一元素
例如:

String match = Iterables.getOnlyElement(Iterables.filter(source, predicate));

您为什么有此要求?如果没有更多信息,看起来您应该首先使用
集合
。插入时,行为将更改为引发异常(当然,您必须检查
添加
的返回值)。或者您可以使用MultiSet。或者这是处理各种Iterables的要求吗?@Axel:谢谢您的建议。我从外部接口收到了一个
Iterable
;它可能包含多个符合某些条件的元素(复杂的元素-不仅仅是
.equals()
),而且这是业务逻辑所不允许的(==>
运行时异常
).第三方库在其当前实现中实际上返回了一个
ArrayList
,但我不想依赖它。元素的数量可能非常大,我所需要的只是提取一个元素-这就是为什么我不希望仅为此目的而构建
集的开销。谢谢你的回答;尽管这会不适用于
Iterables
,它绝对是
Collection
s;+1的一个非常好的解决方案。但是,我确实认为您最初是指Collection,因为您编写了它,但是您的方法签名是iterable的,我认为这只是为了保持更高的接口类型,而不是您真正需要的如果至少存在一个项,y代码实际上将遍历集合两次(尽管如果在每一端找到项,它将快速停止)。嘿,如果您决定以任何方式使用集合,则有一个频率(集合c,对象o)不,您的方法实际上不会遍历集合两次,它将从头遍历集合;如果未找到任何内容,它将完成(1次完整遍历)。如果找到,它将在元素处停止(不迭代到末尾),并从末尾遍历集合,不迟于同一元素处停止(总共1次完整或不完整的遍历)。因此,根据性能标准,您的方法非常棒:)如果它是一个单链表,那么在第一次调用时,它必须从一个项目开始到另一个项目。我不知道
Iterables.getonlylement
,这正是我需要的。我应该找时间更好地看看番石榴…@AlexShesterov:是的,番石榴很可爱:)
int index = collection.indexOf(item);
if (index != -1 && index == collection.lastIndexOf(item)) {
    // one and only one
}
String match = Iterables.getOnlyElement(Iterables.filter(source, predicate));