Java 8: groupby with Comparator

I have an int list, for example (1,2,4,6,7,8). I want to know if there is in Java 8 to create a list of lists.

If

(x,y)->x+1=y 

he must be on the same list.

In this example, the output should be:

(1,2), (4), (6,7,8)

I can write as follows:

public static List<List<int>> group(List<int> list, GroupFunctionByOrder groupFunction) {

    List<List<int>> result = new ArrayList<>();

    for (int l : list) {

        boolean groupFound = false;
        for (List<int> group : result) {
            if (groupFunction.sameGroup(l, group.get(group.size()-1))) {
                group.add(l);
                groupFound = true;
                break;
            }
        }

        if (! groupFound) {
            List<int> newGroup =  new ArrayList<>();
            newGroup.add(l);
            result.add(newGroup);
        }
    }

    return result;
}

public class GroupFunctionByOrder {
    public boolean sameGroup(int l1, int  l2){
        return l1+1 == l2;
    }
}
+4
source share
4 answers

You can do this using the StreamEx library :

List<List<Integer>> grouped = StreamEx.of(1,2,4,6,7,8)
        .groupRuns((x, y) -> x + 1 == y)
        .toList();
+5
source

No, this is hardly possible.

Due to the nature of the flows, you don’t have an understanding of what value will be processed further, and you cannot pull values ​​from an arbitrary point in the stream. Doing something like this is not possible in terms of Java threads.

BiFunction BiPredicate . , , .

+1

What works in java7 also works in java8 :)

import java.util.*;


public class Main {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1,2,4,6,7,8);
        List<List<Integer>> result = new ArrayList<>();

        List<Integer> prev = new ArrayList<>();
        prev.add(list.get(0));

        //iterate over the list
        for (int i = 1 ; i < list.size(); i++){
            // Add to list if does not satisfy condition
            if (list.get(i) != list.get(i-1) +1){
                result.add(prev);
                prev = new ArrayList();
            }
            prev.add(list.get(i));
        }

        result.add(prev);

        // print result
        for(List<Integer> p : result) {
            Object[] arr = p.toArray();
            System.out.print(Arrays.deepToString(arr));
        }


    }
}
+1
source

I do not know directly in Java 8, but here is an alternative solution:

List<Integer> list = List.of(1, 2, 4, 6, 7, 8);

List<List<Integer>> result = new ArrayList<>();
int start = 0, i = 1, size = list.size();
while (i < size) {
    while (i < size && list.get(i - 1) + 1 == list.get(i)) i++;
    result.add(list.subList(start, i));
    start = i++;
}

System.out.println(result); // [[1, 2], [4], [6, 7, 8]]

In this case, it is used List.subList, which returns the kind of sublist supported by the original list. The idea behind this code is to shift the index until the condition breaks, add a count to the result, and then start from that point again.

0
source

Source: https://habr.com/ru/post/1692517/


All Articles