Reputation: 4062
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 User
to be .equals()
to some described User
, just to have the same username.
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:
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>
Anyone know how?
Upvotes: 101
Views: 156616
Reputation: 1
Ways to all the index Iterate over the index and get all the index
IntStream.range(0, list.size())
.filter(i -> Objects.equals(list.get(i), target)).forEach(System.out::println);
Upvotes: -1
Reputation: 11
Find If present then Return result based on that.
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();
Is starting from 1 so we want to get index so we are subtracting 1 from index
More Shorter
return Arrays.stream(nums)
.peek((num) -> index.incrementAndGet())
.filter(num -> num == target)
.findFirst()
.orElse(-1) == -1 ? -1 : index.get()-1;
Upvotes: 1
Reputation: 2504
Try This:
IntStream.range(0, users.size())
.filter(userInd-> users.get(userInd).getName().equals(username))
.findFirst()
.getAsInt();
Upvotes: 29
Reputation: 6686
There is the detectIndex
method in the Eclipse Collections library which takes a Predicate
.
int index = ListIterate.detectIndex(users, user -> username.equals(user.getName()));
If you have a method on User
class which returns boolean
if username
matches you can use the following:
int index = ListIterate.detectIndexWith(users, User::named, username);
Note: I a committer for Eclipse Collections
Upvotes: 3
Reputation: 36154
Using Guava library: int index =
Iterables.indexOf(users, u -> searchName.equals(u.getName()))
Upvotes: 23
Reputation: 61
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
Upvotes: 6
Reputation: 11250
Occasionally there is no pythonic zipWithIndex
in java. So I came across something like that:
OptionalInt indexOpt = IntStream.range(0, users.size())
.filter(i -> searchName.equals(users.get(i)))
.findFirst();
Alternatively you can use zipWithIndex
from protonpack library
Note
That solution may be time-consuming if users.get is not constant time operation.
Upvotes: 133
Reputation: 6036
You can try StreamEx library made by Tagir Valeev. That library has a convenient #indexOf method.
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);
Upvotes: 11