Stream Way для получения индекса первого элемента, соответствующего логическому
У меня есть List<Users>
. Я хочу получить индекс (первого) пользователя в потоке с конкретным именем пользователя. Я не хочу на самом деле требовать, чтобы User
был .equals()
для описанного User
, просто чтобы иметь одно и то же имя пользователя.
Я могу придумать уродливые способы сделать это (повторить и подсчитать), но похоже, что должен быть хороший способ сделать это, возможно, используя Streams. Пока что лучшее, что у меня есть:
int index = users.stream()
.map(user -> user.getName())
.collect(Collectors.toList())
.indexOf(username);
Это не худший код, который я когда-либо писал, но это не здорово. Это также не так гибко, поскольку он полагается на наличие функции сопоставления с типом с функцией .equals()
, которая описывает свойство, которое вы ищете; Я бы предпочел что-то, что могло бы работать для произвольного Function<T, Boolean>
Кто-нибудь знает как?
Ответы
Ответ 1
Иногда в java нет pythonic zipWithIndex
. Поэтому я наткнулся на что-то вроде этого:
OptionalInt indexOpt = IntStream.range(0, users.size())
.filter(i -> searchName.equals(users.get(i)))
.findFirst();
В качестве альтернативы вы можете использовать zipWithIndex
из protonpack библиотека
Примечание
Это решение может занять много времени, если users.get не является постоянной операцией времени.
Ответ 2
Попробуйте следующее:
IntStream.range(0, users.size())
.filter(userInd-> users.get(userInd).getName().equals(username))
.findFirst()
.get();
Ответ 3
Вы можете попробовать библиотеку 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);
Ответ 4
Решение без какой-либо внешней библиотеки
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;
просмотреть индекс приращения i, в то время как предикат ложен, следовательно, когда предикат истинен, я на 1 больше, чем сопоставленный предикат => i.get() -1