Splitting List into sublists along elements

后端 未结 13 1939
野趣味
野趣味 2020-11-28 21:51

I have this list (List):

[\"a\", \"b\", null, \"c\", null, \"d\", \"e\"]

And I\'d like something like this:

13条回答
  •  佛祖请我去吃肉
    2020-11-28 22:42

    Here's another approach, which uses a grouping function, which makes use of list indices for grouping.

    Here I'm grouping the element by the first index following that element, with value null. So, in your example, "a" and "b" would be mapped to 2. Also, I'm mapping null value to -1 index, which should be removed later on.

    List list = Arrays.asList("a", "b", null, "c", null, "d", "e");
    
    Function indexGroupingFunc = (str) -> {
                 if (str == null) {
                     return -1;
                 }
                 int index = list.indexOf(str) + 1;
                 while (index < list.size() && list.get(index) != null) {
                     index++;
                 }
                 return index;
             };
    
    Map> grouped = list.stream()
                   .collect(Collectors.groupingBy(indexGroupingFunc));
    
    grouped.remove(-1);  // Remove null elements grouped under -1
    System.out.println(grouped.values()); // [[a, b], [c], [d, e]]
    

    You can also avoid getting the first index of null element every time, by caching the current min index in an AtomicInteger. The updated Function would be like:

    AtomicInteger currentMinIndex = new AtomicInteger(-1);
    
    Function indexGroupingFunc = (str) -> {
            if (str == null) {
                return -1;
            }
            int index = names.indexOf(str) + 1;
    
            if (currentMinIndex.get() > index) {
                return currentMinIndex.get();
            } else {
                while (index < names.size() && names.get(index) != null) {
                  index++;
                }
                currentMinIndex.set(index);
                return index;
            }
        };
    

提交回复
热议问题