Stream Way to get index of first element matching boolean
我有一个
我可以想到执行此操作的丑陋方法(重复和计数),但感觉应该有一种不错的方法(可能是通过使用Streams来执行此操作)。 到目前为止,我拥有的最好的是:
1 2 3 4 | int index = users.stream() .map(user -> user.getName()) .collect(Collectors.toList()) .indexOf(username); |
这不是我编写过的最糟糕的代码,但这不是很好。 它也不是那么灵活,因为它依赖于一个具有
有人知道吗?
有时Java中没有pythonic
1 2 3 | OptionalInt indexOpt = IntStream.range(0, users.size()) .filter(i -> searchName.equals(users.get(i))) .findFirst(); |
或者,您可以使用来自protonpack库的
注意
如果users.get不是恒定时间操作,则该解决方案可能很耗时。
尝试这个:
1 2 3 4 | IntStream.range(0, users.size()) .filter(userInd-> users.get(userInd).getName().equals(username)) .findFirst() .get(); |
您可以尝试Tagir Valeev制作的StreamEx库。该库具有方便的#indexOf方法。
这是一个简单的示例:
1 2 3 4 5 | 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); |
没有任何外部库的解决方案
1 2 3 4 5 | AtomicInteger i = new AtomicInteger(); // any mutable integer wrapper int index = users.stream() .peek(v -> i.incrementAndGet()) .anyMatch(user -> user.getName().equals(username)) ? // your predicate i.get() - 1 : -1; |
谓词为false时的peek增量索引i,因此当谓词为true时,我比匹配的谓词多1 =>
Eclipse Collections库中有一个
1 | int index = ListIterate.detectIndex(users, user -> username.equals(user.getName())); |
如果
1 | int index = ListIterate.detectIndexWith(users, User::named, username); |
注意:我是Eclipse Collections的提交者
使用Guava库:
Iterables.indexOf(users, u -> searchName.equals(u.getName()))