Find all indexes of a value in a List
Solution 1
Explanation
The method List#indexOf
only returns the index of the first found matching element. From its documentation:
Returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element. [...]
But you want all, therefore you also need to iterate all elements.
Also note that calling List#contains
is not necessary since List#indexOf
also answers this question, it returns -1
if not found. In fact in an ArrayList
both calls are very expensive (they iterate from left to right until found) so you shouldn't use unnecessary statements if they are such expensive.
Solution
Instead just iterate all elements and collect the ones that match:
ArrayList<String> author = ...
String needle = ...
// Collect matches
List<Integer> matchingIndices = new ArrayList<>();
for (int i = 0; i < author.size(); i++) {
String element = author.get(i);
if (needle.equals(element)) {
matchingIndices.add(i);
}
}
// Print matches
matchingIndices.forEach(System.out::println);
Or you may use some of the very convenient methods of the Stream API. Stream#filter
(documentation) for example:
List<Integer> matchingIndices = IntStream.range(0, author.size())
.filter(i -> needle.equals(author.get(i))) // Only keep those indices
.collect(Collectors.toList());
Solution 2
You could go over the entire list and save all the indexes that match the search term. Java 8's steams give you a pretty elegant way of doing this:
int[] indexes =
IntStream.range(0, names.size())
.filter(i -> names.get(i).equals(search))
.toArray();
Related videos on Youtube
PeterSchmit
Updated on June 04, 2022Comments
-
PeterSchmit almost 2 years
I'm trying to search an
ArrayList
for a user input. I've managed to create a search that prints the index of the first occurrence from within the list.I'm having trouble trying to get the rest of the indexes that the item are stored.
Here is the code I have got so far to print the first index of
search
:if (names.contains(search)) { System.out.println("name found!"); System.out.println(names.indexOf(search)); }
I understand that a loop needs to be added. But I am having trouble trying to formulate it.
Example
ArrayList<String> names = new ArrayList<String>(); names.add("Bob"); names.add("Jerry"); names.add("Bob"); names.add("Mick");
Say
search = "Bob"
. My expected result would be{0,2}
. Instead, I am only able to get the index of the first occurrence (0
).assert allIndexesOf(names, "Bob").equals(List.of(0, 2)); [...] private List<Integer> allIndexesOf(List<?> list, Object o) { // How can this be implemented? }
How can I get all indexes that match the search string?
-
JB Nizet over 6 yearsForget programming for a while. Imagine you have 10 drawers, numbered from 0 to 9, and want to find all the drawers containing a blue sheet of paper, and write their number on a sheet of paper. How do you do?
-
ollie over 6 yearsOkay - seems like a school assignment, so I will be very high level to help with the logic. for all items in the list, if the item at the current index is what I'm looking for, then add to a different list the index, else don't do anything and move on
-
Zabuzard over 6 yearsQuestions asking for homework help must include a summary of the work you've done so far to solve the problem, and a description of the difficulty you are having solving it (help center, How to Ask). - You have done all that, nice!
-
M. Justin about 3 yearsVoting to reopen. The "duplicate" question is about characters within a string, not elements within a list. While they have similar APIs, they are not identical. Further, there are other solutions (e.g. streams) that may be more appropriate than
indexOf
for Lists.
-
-
Zabuzard over 6 yearsBut then he looses the indices. I think he wants to collect the indices, not the elements (since they are equal).
-
Mureinik over 6 years@Zabuza you should read my solution again - it does collect the indexes.
-
S.R.I over 6 yearsIn the present form, I think this is a poor question. As JB Nizet said, there's a bigger question to be tackled here.
-
Zabuzard over 6 yearsAh indeed, thought you had done a
map
and thus loosing track of the indices. -
Zabuzard over 6 yearsAvoid comparing
String
with==
. The result is probably not what you expected. Exchange it withString#equals
and it will be fine. -
Zabuzard over 6 yearsMore on this SO: How do I compare strings in Java?
-
Silvan over 6 yearsThanks for the hint. I edited my post.
-
M. Justin about 3 years@S.R.I I think it's a fine question. I actually had this come up today in a decidedly non-homework problem.
-
Delrius Euphoria over 2 yearsWouldn't it be better to start from first index of occurrence of item rather than from 0th position?
-
Zabuzard over 2 years@CoolCloud Sure, if you know that index beforehand already... but if your suggesting to use something like
indexOf
, you are not really gaining anything. Since that method will also just simply iterate.