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

kdfy810k  于 2023-02-07  发布在  Java
关注(0)|答案(7)|浏览(118)

我有一个List<Users>。我想获得流中具有特定用户名的(第一个)用户的索引。我不想实际上要求User.equals()到一些描述的User,只是为了具有相同的用户名。
我可以想出一些丑陋的方法(迭代和计数),但我觉得应该有一个很好的方法来做这件事,可能是通过使用流。

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

这不是我写过的最差的代码,但也不是很好,而且也不是很灵活,因为它依赖于一个Map函数,该函数通过.equals()函数来描述你要寻找的属性;我更希望有一个可以对任意Function<T, Boolean>工作的程序
有人知道怎么做吗?

wwodge7n

wwodge7n1#

在java中偶尔也会出现pythonic zipWithIndex,所以我遇到了类似的情况:

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

或者,您可以使用protonpack库中的zipWithIndex

附注

  • 如果users.get不是常数时间操作,则该解决方案可能会非常耗时。*
62o28rlo

62o28rlo2#

试试这个:

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

toe950273#

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

zzlelutf

zzlelutf4#

你可以试试Tagir Valeev制作的StreamEx库,这个库有一个方便的#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);
bvjveswy

bvjveswy5#

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

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;

predicate 为假时peek递增索引i因此 predicate 为真时i比匹配 predicate 大1 =〉i.get() -1

8cdiaqws

8cdiaqws6#

Eclipse Collections库中有一个detectIndex方法,它接受一个Predicate

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

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

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

注意:我是Eclipse集合的提交者

qc6wkl3g

qc6wkl3g7#

    • 查找是否存在,然后根据查找结果返回结果。**

1.确定元素是否存在。
1.如果存在,则返回索引,否则返回-1

AtomicInteger index = new AtomicInteger();
    int result =  Arrays.stream(nums)
                         .peek((num) -> index.incrementAndGet())
                         .filter(num -> num == target)
                         .findFirst()
                         .orElse(-1);
    return result == -1 ? result : index.get()-1;
AtomicInteger index = new AtomicInteger();

从1开始,所以我们要得到index,所以我们要从index中减去1

    • 更短**
return Arrays.stream(nums)
                     .peek((num) -> index.incrementAndGet())
                     .filter(num -> num == target)
                     .findFirst()
                     .orElse(-1) == -1 ? -1 : index.get()-1;

相关问题