Java 获取匹配布尔值的第一个元素的索引的流方式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38963338/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 20:46:58  来源:igfitidea点击:

Stream Way to get index of first element matching boolean

javajava-8java-stream

提问by Edward Peters

I have a List<Users>. I want to get the index of the (first) user in the stream with a particular username. I don't want to actually require the Userto be .equals()to some described User, just to have the same username.

我有一个List<Users>. 我想使用特定用户名获取流中(第一个)用户的索引。我不想实际要求User成为.equals()某些描述的User,只是为了具有相同的用户名。

I can think of ugly ways to do this (iterate and count), but it feels like there should be a nice way to do this, probably by using Streams. So far the best I have is:

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

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

Which isn't the worst code I've ever written, but it's not great. It's also not that flexible, as it relies on there being a mapping function to a type with a .equals()function that describes the property you're looking for; I'd much rather have something that could work for arbitrary Function<T, Boolean>

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

Anyone know how?

有谁知道怎么做?

采纳答案by vsminkov

Occasionally there is no pythonic zipWithIndexin java. So I came across something like that:

有时zipWithIndexjava中没有pythonic 。所以我遇到了这样的事情:

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

Alternatively you can use zipWithIndexfrom protonpacklibrary

或者您可以使用zipWithIndexprotonpack

Note

笔记

That solution may be time-consuming if users.get is not constant time operation.

如果 users.get 不是恒定时间操作,该解决方案可能会很耗时。

回答by AmanSinghal

Try This:

尝试这个:

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

回答by SerCe

You can try StreamExlibrary made by Tagir Valeev. That library has a convenient #indexOf method.

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

This is a simple example:

这是一个简单的例子:

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);

回答by hibour

A solution without any external library

没有任何外部库的解决方案

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;

peek increment index i while predicate is false hence when predicate is true i is 1 more than matched predicate => i.get() -1

在谓词为假时查看增量索引 i 因此当谓词为真时 i 比匹配的谓词多 1 => i.get() -1

回答by karmakaze

Using Guava library: int index = Iterables.indexOf(users, u -> searchName.equals(u.getName()))

使用番石榴库: int index = Iterables.indexOf(users, u -> searchName.equals(u.getName()))

回答by Donald Raab

There is the detectIndexmethod in the Eclipse Collectionslibrary which takes a Predicate.

还有就是detectIndex在方法Eclipse的收藏库,这需要Predicate

int index = ListIterate.detectIndex(users, user -> username.equals(user.getName()));

If you have a method on Userclass which returns booleanif usernamematches you can use the following:

如果您在User类上有一个boolean如果username匹配则返回的方法,您可以使用以下方法:

int index = ListIterate.detectIndexWith(users, User::named, username);

Note: I a committer for Eclipse Collections

注意:我是 Eclipse Collections 的提交者