wannaBeDev
wannaBeDev

Reputation: 739

split a list into sublists by grouping **only** repeated elements that are adjacent to each other

Is there a simple way to split a list into sublists by grouping only repeated elements that are adjacent to each other?

Simple example with the folowing list of strings:

Input:  [RED,RED,BLUE,BLUE,BLUE,GREEN,BLUE,BLUE,RED,RED]

Output:  [[RED,RED],[BLUE,BLUE,BLUE],[GREEN],[BLUE,BLUE],[RED,RED]]

If I use groupingBy from java streams all elements which are equal will end up in the same sublist, which I want to avoid. Any ideas?

Upvotes: 2

Views: 257

Answers (2)

Eng.Fouad
Eng.Fouad

Reputation: 117627

You can create a custom collector:

List<String> input = Arrays.asList("RED", "RED", "BLUE", "BLUE", "BLUE", "BLUE", "RED", "RED");
List<List<String>> output = input.stream()
        .collect(Collector.of(ArrayList::new, (accumulator, item) ->
        {
            if(accumulator.isEmpty())
            {
                List<String> list = new ArrayList<>();
                list.add(item);
                accumulator.add(list);
            }
            else
            {
                List<String> last = accumulator.get(accumulator.size() - 1);
                if(last.isEmpty() || last.get(0).equals(item)) last.add(item);
                else
                {
                    List<String> list = new ArrayList<>();
                    list.add(item);
                    accumulator.add(list);
                }
            }
        }, (left, right) -> {left.addAll(right); return left;}));

Upvotes: 3

Ryan
Ryan

Reputation: 1760

I'm sure there's a better way to do this with streams, but for a quick and dirty:

List<String> values = Arrays.asList("RED", "RED", "BLUE", "BLUE", "BLUE", "BLUE", "RED", "RED");
    List<List<String>> output = new ArrayList<List<String>>();
    String previous = null;
    List<String> subList = new ArrayList<String>();
    for (String value : values) {
        if (previous == null || value.equals(previous)) {
            subList.add(value);
        } else {
            output.add(subList);
            subList = new ArrayList<String>();
            subList.add(value);
        }
        previous = value;
    }
    if (!subList.isEmpty()) {
        output.add(subList);
    }
    System.out.println(output);

Upvotes: 2

Related Questions