Reputation: 563
I've been trying to solve this for a while but my Java 8 skills need a bit of work.
This issue I am having is that in an IntStream
. I am using a filter to call a predicate which will run some logic on the current item and the next item in the list.
return IntStream.range(0, someList.size() - 1)
.filter(n -> someMethod(someList.get(n), someList.get(n + 1)))
.mapToObj(i -> ((Integer) i).toString())
.collect(Collectors.joining(", "));
The problem is that the last item is not checked.
So say I have 10 items in the list the first iteration would look at items 0 and 1, then 1 and 2 etc until we get to 10 and IndexOutOfBounds
.
No error is thrown here which is strange although probably expected in Java 8?
How can I say something like "if we get an index out of bounds just return true"?
I hope this makes sense. Cheers
Upvotes: 2
Views: 4807
Reputation: 1622
Let say someList.size() = 10, so the last element is with index 9. and then you doing something like n+1, which is someList.get(9+1) then Exception occurs. It should be someList.size() - 1
return IntStream.range(0, someList.size()-1)
.filter(n -> someMethod(someList.get(n), someList.get(n + 1)))
.collect(Collectors.toList());
And it should work.
Edit: You need to do some checking
` private void invoke() {
List<String> someList = Arrays.asList("Test", "Super");
int size = someList.size();
List<Integer> collect = IntStream.range(0, size)
.filter(n -> someMethod(someList.get(n), getNext(someList, n + 1)))
.mapToObj(i -> i)
.collect(Collectors.toList());
}
public <T> T getNext(List<T> someList, int index) {
return someList.size() > index ? someList.get(index) : null;
}
public boolean someMethod(String a1, String a2) {
return a1.equals(a2);
}
Upvotes: 0
Reputation: 1258
The second parameter in range() function is exclusive which means if you set it to be 20 your range will go until 19 (not including 20) that in your case you want to get the index before last so if the last index is size-1 you should pass to function size() if you want to get size-2 you should pass last parameter size-1 here is a simple example
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
IntStream.range(0, list.size() - 1).forEach(index -> System.out.println("Me " + list.get(index) + " and my brother " + list.get(index + 1)));
}
Upvotes: 0
Reputation: 8851
You're trying to iterate from 0
to the size+1
, so for a list of size 3, you're attempting to to:
list[0]
- valid
list[1]
- valid
list[2]
- valid
list[3]
- OOB, as list is only size 3
Change it to:
return IntStream.range(0, someList.size())
.filter(n -> n < someList.size()-1 ? someMethod(someList.get(n), someList.get(n+1)) : someOtherMethod(someList.get(n)).collect(Collectors.toList));
This will fix two things. One, it will fix the OOB you had in range()
, and two, it will check that n
is in bounds for calling someMethod for n
and n+1
. You'll need to make another method for how you want to handle it for the last element in the list though
Upvotes: 4