Split list or array when changing sign using streams

Recently, I came across the need to split a list of values ​​into lists of positive and negative numbers. However, NOT one list is positive and one for the negative, but basically a new list starts after the sign changes (ignoring 0 values);

Example:

valuesInList = [-1, -3, -5, -120, 0, 15, 24, 42, 13, -15, -24, -42, 1, 2, 3]
splitList = [[-1, -3, -5, -120], [15, 24, 42, 13], [-15, -24, -42], [1, 2, 3]]

I wrote code that works, but this is what I'm not very happy with:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Main {

    public static void main(String[] args) {
        Byte[] values = new Byte[]{-1, -3, -5, -120, 0, 15, 24, 42, 13, -15, -24, -42, 1, 2, 3}; //0 -> ignore
        List<Byte> valuesInList = Arrays.asList(values);
        System.out.println("valuesInList = " + valuesInList);
        int firstNotZero = valuesInList.stream().filter(b -> b != 0).collect(Collectors.toList()).get(0);
        boolean currentlyLookingForPositive = firstNotZero > 0;

        List<List<Byte>> splitList = new ArrayList<>();

        int index = 0;

        while (index < valuesInList.size()) {
            List<Byte> collection = new ArrayList<>();
            while (currentlyLookingForPositive && index < valuesInList.size()) {
                byte current = valuesInList.get(index);
                if (current > 0) {
                    collection.add(current);
                    index++;
                }
                else
                    currentlyLookingForPositive = false;
                if (current == 0)
                    index++;
            }
            if (!collection.isEmpty())
                splitList.add(collection);

            collection = new ArrayList<>();
            while (!currentlyLookingForPositive && index < valuesInList.size()) {
                byte current = valuesInList.get(index);
                if (current < 0) {
                    collection.add(current);
                    index++;
                }
                else
                    currentlyLookingForPositive = true;
            }
            if (!collection.isEmpty())
                splitList.add(collection);
        }

        System.out.println("splitList = " + splitList);
    }

}

, : . , , .
, , , , Java 8 Java 8, .

: . , - , ( , ) . , (/).

+4
2

:

List<List<Integer>> result = Arrays.asList(-1, -3, -5, -120, 0, 15, 24, 42, 13, -15, -24, -42, 1, 2, 3)
            .stream()
            .collect(Collector.of(
                    () -> {
                        List<List<Integer>> list = new ArrayList<>();
                        list.add(new ArrayList<>());
                        return list;
                    },
                    (list, x) -> {

                        if (x == 0) {
                            return;
                        }

                        if (list.size() == 0) {
                            list.get(0).add(x);
                        } else {
                            List<Integer> lastInner = list.get(list.size() - 1);
                            if (lastInner.size() > 0) {
                                int elem = lastInner.get(0);
                                if (elem >>> 31 == x >>> 31) {
                                    lastInner.add(x);
                                } else {
                                    List<Integer> oneMore = new ArrayList<>();
                                    oneMore.add(x);
                                    list.add(oneMore);
                                }
                            } else {
                                lastInner.add(x);
                            }

                        }

                    }, (left, right) -> {

                        throw new RuntimeException("Not for aprallel");
                    }));

    System.out.println(result);

, ( ). , .

, StreamEx:

List<Integer> input = Arrays.asList(-1, -3, -5, -120, 0, 15, 24, 42, 13, -15, -24, -42, 1, 2, 3);
    List<Integer> filtered = input.stream().filter(x -> x != 0).collect(Collectors.toList());

    int[] indexes = IntStream.range(0, filtered.size() - 2)
            .filter(x -> x == 0 || x == filtered.size() || filtered.get(x) >>> 31 != filtered.get(x + 1) >>> 31)
            .map(x -> x + 1)
            .toArray();

    List<List<Integer>> result = IntStream.range(0, indexes.length - 1)
            .mapToObj(x -> filtered.subList(indexes[x], indexes[x + 1]))
            .collect(Collectors.toList());

    System.out.println(result);
+2

@Flown , , , , , Math # signum.

:

int[] values = new int[]{-1, -3, -5, -120, 0, 15, 24, 42, 13, -15, -24, -42, 1, 2, 3}; //0 -> ignore
IntStream seq = IntStream.of(values).filter(i -> i!=0);
List<List<Integer>> result = 
IntStreamEx.of(seq).boxed().groupRuns((i1, i2) -> Math.signum(i1) == Math.signum(i2)).toList();

, , .

IntStreamEx StreamEx, .

+2

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


All Articles