Я хочу, чтобы объединить внутренние списки с использованием java8 потоков для следующих например:Использование java8 Streams объединить внутренние списки в списке
Когда
List<List<Integer>> mainList = new ArrayList<List<Integer>>();
mainList.add(Arrays.asList(0,1));
mainList.add(Arrays.asList(0,1,2));
mainList.add(Arrays.asList(1,2));
mainList.add(Arrays.asList(3));
должны быть объединены в
[[0,1,2],[3]];
И Когда
List<List<Integer>> mainList = new ArrayList<List<Integer>>();
mainList.add(Arrays.asList(0,2));
mainList.add(Arrays.asList(1,4));
mainList.add(Arrays.asList(0,2,4));
mainList.add(Arrays.asList(3,4));
mainList.add(Arrays.asList(1,3,4));
должны быть объединены в
[[0,1,2,3,4]];
Это до сих пор, что я сделал
static void mergeCollections(List<List<Integer>> collectionTomerge) {
boolean isMerge = false;
List<List<Integer>> mergeCollection = new ArrayList<List<Integer>>();
for (List<Integer> listInner : collectionTomerge) {
List<Integer> mergeAny = mergeCollection.stream().map(
lc -> lc.stream().filter(listInner::contains)
).findFirst()
.orElse(null)
.collect(Collectors.toList());
}
}
, но я получаю это исключение:
Exception in thread "main" java.lang.NullPointerException
at linqArraysOperations.LinqOperations.mergeCollections(LinqOperations.java:87)
Обновлено с противоминной версии ответа
Вот чего я хочу достичь, но отличный ответ Тагира без рекурсии
меняю вещи немного в Mikhaal ответ для достижения этой цели, используя логику от Тагир ответа без плоской карты
public static <T> List<List<T>> combineList(List<List<T>> argList) {
boolean isMerge = false;
List<List<T>> result = new ArrayList<>();
for (List<T> list : argList) {
List<List<T>> mergedFound =
result.stream()
.filter(mt->list.stream().anyMatch(mt::contains))
.map(
t -> Stream.concat(t.stream(),list.stream()).distinct()
.collect(Collectors.toList())
)
.collect(Collectors.toList());
//if(mergedFound !=null && (mergedFound.size() > 0 && mergedFound.stream().findFirst().get().size() > 0)){
if(mergedFound !=null && mergedFound.size() > 0 &&){
result = Stream.concat(result.stream().filter(t->list.stream().noneMatch(t::contains)),mergedFound.stream()).distinct().collect(Collectors.toList());
isMerge = true;
}
else
result.add(list);
}
if(isMerge && result.size() > 1)
return combineList(result);
return result;
}
Смотреть отлично !!!! !!! можете ли вы как-то удалить этот единственный цикл, если это возможно? –
@Mohtisham, вы хотите переписать внешний цикл 'for' для Stream API? Ну, технически это операция «reduceLeft» или «foldLeft». У стандартного Stream API нет такой вещи, но если вы не заботитесь о параллелизме, вы можете использовать простой 'reduce', предоставляющий фиктивный комбайнер. Однако это не улучшит код. [Вот реализация] (https://gist.github.com/amaembo/bb65d43ac4202b584ce6c0a29db16aaf), используя мою бесплатную библиотеку [StreamEx] (https://github.com/amaembo/streamex/) (на самом деле имеющую foldLeft). Без StreamEx это выглядело бы еще хуже. –
Я полностью потерян, чтобы понять, что происходит, можете ли вы прокомментировать, что делает ваш код для обоих случаев. Я знаю, что это большой вопрос и странный, но я чувствую себя совершенно беспомощным, чтобы зачать свое искусство. –