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.
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?
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.
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());