I have a list of integers and I want to return sub lists of integers from this list using java 8 streams where my sub list contain all the positive integers from original list just before it encounters a negative integer
For ex. let's say my list have elements
[1 , 2 , 0 , -1 , 5 , 8 , 9 , -11 , 7 , 13 ]
then I should return sub lists containing
[1 , 2 , 0 ] [ 5 , 8 , 9 ] [7 , 13]
I tried following approach but it's not working, your direction & input is much appreciated.
package Java8;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
public class StreamsExamples {
public static void main(String[] args) {
ArrayList<Integer> arr = new ArrayList<Integer>();
arr.add(1);
arr.add(2);
Integer[] al = new Integer[]{0,-1,5,8,9,-11,7,13};
arr.addAll(Arrays.asList(al));
arr.stream().collect(Collectors.groupingBy(Functionality::getPositiveList));
// arr.stream().collect(Collectors.toList()).;
//arr.stream().sorted().forEach(System.out::print);
}
}
class Functionality{
public List<List<Integer>> getPositiveList(List<Integer> list){
List<List<Integer>> li = new ArrayList<List<Integer>>();
List<Integer> a = new ArrayList<Integer>();
for(int i=0;i<list.size();i++) {
if(list.get(i)>=0) {
a.add(list.get(i));
}
else if (list.get(i)<0) {
li.add(a);
a.clear();
}
}
return li;
}
}
This isn't so hard if you think a bit different here: find out the indexes where the negative value is and just do a subList between those... There are some quirks to do with IntStream.of(-1) (but I'll let you figure it out why it is like that: try to replace it with the more intuitive IntStream.of(0) and see what is going on). So having an input like:
ArrayList<Integer> arr = List.of(1, 2, 0, -1, 5, 8, 9, -11, 7, 13);
You first find out the indexes:
int[] indexes = IntStream.concat(
IntStream.of(-1),
IntStream.concat(
IntStream.range(0, arr.size())
.filter(x -> arr.get(x) < 0),
IntStream.of(arr.size())))
.toArray();
System.out.println(Arrays.toString(indexes));
This will give a result like: [-1, 3, 7, 10].
Thus just compute the subList between these:
IntStream.range(0, indexes.length - 1)
.mapToObj(x -> arr.subList(indexes[x] + 1, indexes[x + 1]))
.collect(Collectors.toList())
.forEach(System.out::println);
It's a bit ugly, but this works:
List<List<Integer>> lists = Arrays.stream(arr).boxed()
.reduce(
new ArrayList<>(),
(l, i) -> {
if (l.isEmpty() || i < 0) {
l.add(new ArrayList<>());
}
if (i >= 0) {
l.get(l.size() - 1).add(i);
}
return l;
}, (a, b) -> {
a.addAll(b);
return a;
});
Tested:
int [] arr = {1, 2, 0, -1, 5, 8, 9, -11, 7, 13};
List<List<Integer>> lists = Arrays.stream(arr).boxed().reduce(new ArrayList<>(),
(l, i) -> {
if (l.isEmpty() || i < 0) {
l.add(new ArrayList<>());
}
if (i >= 0) {
l.get(l.size() - 1).add(i);
}
return l;
}, (a, b) -> {
a.addAll(b);
return a;
});
System.out.println(lists);
Output:
[[1, 2, 0], [5, 8, 9], [7, 13]]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With