Stream方式获取第一个元素匹配的索引boolean

问题描述:

我有一个List<Users>。我想用特定的用户名来获取流中(第一个)用户的索引。我不想实际要求User.equals(),某些描述为User,只是为了拥有相同的用户名。Stream方式获取第一个元素匹配的索引boolean

我可以想到丑陋的方法来做到这一点(迭代和计数),但它感觉应该有一个很好的方式来做到这一点,可能通过使用流。到目前为止,我拥有的最好的是:

int index = users.stream() 
    .map(user -> user.getName()) 
    .collect(Collectors.toList()) 
    .indexOf(username); 

这不是我写过的最差的代码,但它不是很好。它也不是那么灵活,因为它依赖于存在一个映射函数,该映射函数的类型为.equals()函数,该函数描述了您正在查找的属性;我宁愿有东西可以为任意工作Function<T, Boolean>

任何人都知道如何?

+2

为什么是 “迭代” *丑*? – Andreas

+2

流和索引混合不好。在这一点上,你通常会更好地回到旧式循环。 –

+1

@Andreas我喜欢关于流的东西,是将集合相关的逻辑与所要求的特定事物分离。在这种情况下,有很多不同的问题可能会被问到,只是从核心'Function '不同,所以感觉应该有一种方法来处理将它从通用集合逻辑中抽象出来的方法。 –

java中偶尔没有pythonic zipWithIndex。所以,我碰到的东西来了,如同是:

OptionalInt indexOpt = IntStream.range(0, users.size()) 
    .filter(i -> searchName.equals(users.get(i))) 
    .findFirst(); 

或者您可以使用zipWithIndexprotonpack

注意

该解决方案可耗时如果users.get不恒定的时间操作。

+0

这是有效的。我也可以通过在过滤器操作中查找具有给定索引的用户来跳过这一对......不知道这是好还是坏。 –

+0

@EdwardPeters好点!我会编辑我的答案 – vsminkov

+0

@EdwardPeters这绝对会更好。至少,这消除了额外的内存流量 – vsminkov

试试这个:

IntStream.range(0, users.size()) 
    .filter(userInd-> users.get(userInd).getName().equals(username)) 
    .findFirst() 
    .get(); 
+0

这让我的用户,但不是索引 –

+0

我已经更新了解决方案找到索引。 – AmanSinghal

+5

希望找到一个用户,或代码崩溃。 – Andreas

您可以尝试StreamEx库由Tagir Valeev制造。该库有一个方便的#indexOf方法。

这是一个简单的例子:

List<User> users = asList(new User("Vas"), new User("Innokenty"), new User("WAT")); 
long index = StreamEx.of(users) 
     .indexOf(user -> user.name.equals("Innokenty")) 
     .getAsLong(); 
System.out.println(index);