Home > front end >  Merge multiple list of string in unique list in java 8
Merge multiple list of string in unique list in java 8

Time:05-25

I have 3 list of strings:

List<String> collect1 =Arrays.asList("1","2","julie","4","5","julie","7","8","9","10","11")

List<String> collect2 =Arrays.asList("1","2","3","4","john","6","7","8","9","john","11")

List<String> collect3 =Arrays.asList("1","jack","3","4","5","6","7","8","jack","10","11")

I want to merge all of them into each other and duplicate values should not be deleted to have below list would be better with use java 8:

{ "1","jack","julie","4","john","julie","7","8","jack","john","11" }

Thanks!

CodePudding user response:

Edit 1: I am not sure what you mean with:

merge all of them into each other and duplicate values should not be deleted to have below list

I am assuming you mean to return a list whose values are present in all three lists (common elements shared by all lists) which also includes the duplicate values inside respective lists.

Maybe you can find the intersection between 3 lists (finding common elements among them) and then append the duplicates value from each list - However, one can think of a case where all the lists contain same duplicate values e.g list1 = [1 1], list2 = [1 1] and list3 = [1 1]. How many 1s do you want on your final result?)

    // merge lists together - only common elements
    List<String> intersect = list1
        .stream()
        .filter(list2::contains)
        .filter(list3::contains)
        .collect(Collectors.toList());
    
    // iterate through your lists
    List<List<String>> listAll = Arrays.asList(list1, list2, list3);
    for (List<String> list: listAll) {
        // find duplicates inside each the list
        Set<String> items = new HashSet<>();
        List<String> duplicateValue = list
           .stream()
           .filter(n -> !items.add(n))
           .collect(Collectors.toList());
        // add to the duplicate to the final result
        intersect.addAll(duplicateValue);
        intersect.addAll(duplicateValue);
    }
    

Output: [1, 4, 7, 8, 11, julie, julie, john, john, jack, jack] where 1, 4, 7, 8, 11 are common on all lists, while the names are duplicates in respective single list


However, if you just want to merge all values of the lists together, there are a couple of ways you can do that:

Use Stream (https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html) to combine the lists. Create a stream with lists and then flatten it to retrieve all elements

List<String> uniqueList = Stream.of(list1, list2, list3)
    .flatMap(Collection::stream).collect(Collectors.toList());

or

List<String> uniqueList = new ArrayList<>();
Stream.of(list1, list2, list3).forEach(joinedList::addAll);

See this related question for more details: Combine multiple lists in Java

CodePudding user response:

I want to merge all of them into each other and duplicate values should not be deleted

If you want to preserve only duplicates and each element should appear only once in the resulting list, you can create an intermediate map Map<String, Boolean>, that would associate each unique string with a boolean value denoting whether it is a duplicate or not.

Then create a stream over the set of map entries, filter out the duplicates and collect the remained keys into a list.

List<String> result = Stream.of(collect1, collect2, collect3)
    .flatMap(List::stream)
    .collect(Collectors.toMap(
        Function.identity(),
        str -> false,         // first occurence - key isn't proved to be a duplicate
        (left, right) -> true // is a duplicate
    ))
    .entrySet().stream()
    .filter(Map.Entry::getValue)
    .map(Map.Entry::getKey)
    .collect(Collectors.toList());

CodePudding user response:

Not the best implementation but it do the work :

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

public class Application {
    public static void main(String[] args) {
        List<String> collect1 = Arrays.asList("1", "2", "julie", "4", "5", "julie", "7", "8", "9", "10", "11");
        List<String> collect2 = Arrays.asList("1", "2", "3", "4", "john", "6", "7", "8", "9", "john", "11");
        List<String> collect3 = Arrays.asList("1", "jack", "3", "4", "5", "6", "7", "8", "jack", "10", "11");

        // the range here is the number of element of the arrays from 0 inclusive to 11 exclusive
        List<String> result = IntStream.range(0, 11).mapToObj(i -> {
            String first = collect1.get(i);
            String second = collect2.get(i);
            String third = collect3.get(i);
            if (first.equals(second) && second.equals(third))
                return first;
            else if (!first.chars().allMatch(Character::isDigit)) {
                return first;
            } else if (!second.chars().allMatch(Character::isDigit)) {
                return second;
            } else {
                return third;
            }

        }).collect(Collectors.toList());

        System.out.println("    ######################################");
        System.out.println(result);
        System.out.println("    ######################################");

    }
}

Output :

    ######################################
[1, jack, julie, 4, john, julie, 7, 8, jack, john, 11]
    ######################################
  • Related