Как сравнить 2 списка, используя Stream, и получить список сравнения форм элементов? - PullRequest
1 голос
/ 18 марта 2020
//FullName(String name, String fullName)
List<FullName> fullNameList = Arrays.asList(
            new FullName("Alpha", "Alpha Maz"),
            new FullName("Beta", "Beta Sew"),
            new FullName("Delta", "Delta Non"),
            new FullName("Indigo", "Indigo Loe")
            );

List<String> nameList = Arrays.asList(new String[] {"Delta","Alpha"});

Давайте рассмотрим приведенный выше пример. Я хотел бы сравнить nameList с fullNameList и вернуть полное имя, если найдено какое-либо совпадение.

Мне нужно использовать nameList в качестве основного, так как я хочу, чтобы результат следовал последовательности в nameList, я понятия не имею, как «собрать» элемент из списка сравнения (fullNameList)

String result= nameList.stream()
            .filter(v -> fullNameList.stream().anyMatch(s -> s.getName().equals(v)))
            .collect(Collectors.joining(","));

Actual Result : "Delta,Alpha"
Expected Result : "Delta Non,Alpha Maz"

Есть идеи, как это сделать с Java 8 Stream?

Ответы [ 4 ]

1 голос
/ 18 марта 2020
Map<String, String> nameMapper = fullNameList.stream()
                    .collect(Collectors.toMap(FullName::getFirstName, FullName::getFullName));

List<String> filteredList = nameList.stream()
                            .filter(nameMapper::containsKey)
                            .map(nameMapper::get)
                            .collect(Collectors.toList());

System.out.println("nameList = " + nameList);
System.out.println("filteredList = " + filteredList);

nameList = [Инди go, Альфа, Дельта] FilterList = [Инди go Loe, Альфа Маз, Дельта Не]

nameList = [Delta, Alpha] FilterList = [Delta Non, Alpha Maz]

Несмотря на то, что при создании карты в реальном времени возникают накладные расходы, если список огромен по количеству, то итерация стоимость будет меньше, поскольку выборка равна O (1), так как сама по себе String с меньшей вероятностью вызовет коллизию sh. В этом случае вы выбираете O (log n).

В случае меньшего списка, я думаю, что ответ Эрана более уместен.

0 голосов
/ 18 марта 2020

С небольшими изменениями в вашем коде вы можете получить ожидаемый результат.

String res = fullNameList.stream().filter(f -> nameList.stream().anyMatch(n -> n.equals(f.getName()))).map(f -> f.getfullName()).collect(Collectors.joining(",")); 

Выход: Alpha Maz, Delta Non

0 голосов
/ 18 марта 2020

Если вы ограничены nameList в качестве основного, то вы можете использовать следующее:

String result = nameList.stream()
                .flatMap(name -> fullNameList.stream()
                        .filter(fullName -> fullName.getName().equals(name))
                        .map(FullName::getFullName)
                )
                .collect(Collectors.joining(","));
0 голосов
/ 18 марта 2020

Вам необходимо использовать map вместо filter для сопоставления короткого имени с соответствующим полным именем.

String result= 
    nameList.stream()
            .map(v -> fullNameList.stream()
                                  .filter(s -> s.getName().equals(v))
                                  .findFirst()
                                  .map(FullName::getFullName))
            .filter(Optional::isPresent)
            .map(Optional::get)
            .collect(Collectors.joining(","));

Это предполагает, что FullName класс имеет метод getFullName() который возвращает данные, которые вы sh собираете.

...