#java #java-8 #java-stream
#java #java-8 #java-stream
Вопрос:
Вопрос прост и может быть решен тысячью способов. Но поскольку я изучаю Java 8, я хотел бы сделать это способом Java 8.
У меня есть два списка строк, например:
List<String> list1 = Arrays.asList("A", "B", "C", "D");
List<String> list2 = Arrays.asList("A", "D", "E");
Я хочу взять первый элемент из list1
и проверить, присутствует ли строка в list2
и создать Map<Boolean, String>
. Что-то вроде этого:
Map<Boolean, String> resultMap = list1.stream().collect(partial -> Collectors.partitioningBy(list2.stream().filter(existing -> matchString(partial, existing))));
private static boolean matchString(String partial, String existing) {
return partial.equals(existing);
}
Приведенный выше код содержит ошибку компиляции в matchString(partial, existing)
:
Неправильный тип 1-го аргумента. Найдено: «, требуется: ‘java.lang.Строка’
Следует отметить несколько моментов: в моем реальном сценарии это не простой список строк, а более сложный объект, и этот объект не переопределяет метод equals
or hashcode
.
Я очень хорошо знаю, что это можно сделать разными способами. Но не мог бы кто-нибудь, пожалуйста, сообщить мне, как мы используем Collectors.partitioningBy
в этом конкретном сценарии.
Комментарии:
1. Вы не объяснили, что
Map<Boolean, String>
представляет. Все, что у нас есть, это фрагмент кода, который не компилируется.2. Что сказал @shmosel: неясно, что должно представлять сопоставление. Как написано, сопоставление должно содержать не более двух элементов: True, сопоставленное со строковым значением, и False, сопоставленное со строковым значением. Я предполагаю, что сопоставление предназначено для ответа на вопрос, является ли конкретное значение из первого списка членом второго списка, и в этом случае, по крайней мере, сопоставление должно быть введено как Map<Строка, логическое значение> .
Ответ №1:
С помощью Collectors.partitioningBy
вы можете получить Map<Boolean, List<String>>
. Из partitioningBy
документа:
Возвращает коллектор, который разделяет входные элементы в соответствии с
Predicate
и организует их вMap<Boolean, List<T>>
.
В вашем случае:
Map<Boolean, List<String>> map = list1.stream()
.collect(Collectors.partitioningBy(list2::contains));
В случае более сложного объекта, который не переопределяет equals
/ hashcode
, вы можете выполнить сравнение по некоторому определенному полю. Предполагая, что у вас есть что-то вроде:
class ComplexObj {
private String id;
...
}
Map<Boolean, List<ComplexObj>> map = list1.stream()
.collect(Collectors.partitioningBy(obj -> list2.stream()
.map(ComplexObj::getId)
.anyMatch(id -> id.equals(obj.getId()))));
Комментарии:
1. Спасибо, но `contains’ не будет работать, потому что hashcode и equals не переопределены
2. @RahulDevMishra в вашем вопросе говорится, что у вас есть два списка
String
. Если у вас действительно есть объекты без надлежащих реализаций hashCode / equals, вы должны включить это в свой вопрос, соответственно. в первую очередь вам не следует говорить о строках.
Ответ №2:
Найдите мою реализацию ниже, используя Collectors.partitioningBy. Я использую метод List.contains() для предиката, и он отлично работает. Пожалуйста, попробуйте поделиться отзывами / предложениями. Спасибо.
package net.javapedia.streams;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class PartitioningByEx1 {
public static void main(String[] args) {
List<String> list1 = Arrays.asList("A", "B", "C", "D");
List<String> list2 = Arrays.asList("A", "D", "E");
list1.stream().collect(Collectors.partitioningBy(item -> list2.contains(item)))
.forEach((key, val) -> System.out.println(key "-->>" val));
}
}
Вывод программы: