Сначала я бы предложил найти все подгруппы. Для этого вы можете использовать Stream.collect()
с пользовательским коллектором:
List<List<Integer>> sublists = IntStream.of(1, 1, 1, 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 5, 4, 4, 4, 6)
.collect(ArrayList::new, (lists, value) -> {
if (lists.isEmpty() || lists.get(lists.size() - 1).stream().noneMatch(e -> e == value)) {
lists.add(new ArrayList<>());
}
lists.get(lists.size() - 1).add(value);
}, (l1, l2) -> {
throw new RuntimeException("not supported for parallel streams");
});
Результат:
[[1, 1, 1], [2], [1, 1], [3, 3, 3, 3, 3, 3, 3, 3, 3, 3], [4, 4, 4], [5], [4, 4, 4], [6]]
Теперь вы можете использовать это для группировки размеров списка:
Map<Integer, Long> result = sublists.stream()
.collect(Collectors.groupingBy(List::size, Collectors.counting()));
result.forEach((size, count) -> System.out.println(String.format("size %s count %s", size, count)));
Находит все существующие размеры групп и печатает:
size 1 count 3
size 2 count 1
size 3 count 3
size 10 count 1
Для подсчета всех групп с минимальной длиной вы можете использовать:
Map<Integer, Long> result = IntStream.rangeClosed(1, sublists.stream().mapToInt(List::size).max().orElse(0)).boxed()
.collect(Collectors.toMap(Function.identity(), i -> sublists.stream().filter(l -> l.size() >= i).count()));
result.forEach((size, count) -> System.out.println(String.format("size %s count %s", size, count)));
Это печатает:
size 1 count 8
size 2 count 5
size 3 count 4
size 4 count 1
size 5 count 1
size 6 count 1
size 7 count 1
size 8 count 1
size 9 count 1
size 10 count 1
Чтобы получить только предопределенный набор размеров (например, 1, 2, 6, 8
), вы можете изменить последнее решение:
Map<Integer, Long> result = IntStream.of(1, 2, 6, 8).boxed()
.collect(Collectors.toMap(Function.identity(), i -> sublists.stream().filter(l -> l.size() >= i).count()));
result.forEach((size, count) -> System.out.println(String.format("size %s count %s", size, count)));
Результат этого:
size 1 count 8
size 2 count 5
size 6 count 1
size 8 count 1