Подтвердить что ты не робот

Hashmap с потоками в Java 8 Потоки для сбора значения карты

Рассмотрим хэш-карту

Map<Integer, List> id1 = new HashMap<Integer,List>();

Я вставил некоторые значения в оба хэш файла.

Например,

    List<String> list1 = new ArrayList<String>();

    list1.add("r1");
    list1.add("r4");

    List<String> list2 = new ArrayList<String>();
    list2.add("r2");
    list2.add("r5");

    List<String> list3 = new ArrayList<String>();
    list3.add("r3");
    list3.add("r6");

    id1.put(1,list1);
    id1.put(2,list2);
    id1.put(3,list3);
    id1.put(10,list2);
    id1.put(15,list3);

Q1) Теперь я хочу применить условие фильтра к ключу в hashmap и получить соответствующее значение (List).

Например: здесь Мой запрос является ключевым = 1, а вывод должен быть "list1"

Я написал

id1.entrySet().stream().filter( e -> e.getKey() == 1);

Но я не знаю, как получить в качестве списка выход этого потока.

Q2) Снова я хочу применить условие фильтра к ключу в hashmap и получить соответствующий список списков.

Например: здесь мой запрос имеет ключевое value = 1% (ключ может быть 1,10,15), а вывод должен быть "list1", "list2", "list3" (список списков).

4b9b3361

Ответ 1

Если вы уверены, что получите не более одного элемента, который прошел фильтр (что гарантируется вашим фильтром), вы можете использовать findFirst:

Optional<List> o = id1.entrySet()
                      .stream()
                      .filter( e -> e.getKey() == 1)
                      .map(Map.Entry::getValue)
                      .findFirst();

В общем случае, если фильтр может соответствовать нескольким спискам, вы можете собрать их в список списков:

List<List> list = id1.entrySet()
                     .stream()
                     .filter(.. some predicate...)
                     .map(Map.Entry::getValue)
                     .collect(Collectors.toList());

Ответ 2

Что вам нужно сделать, так это создать Stream из Map .entrySet():

// Map<K, V> --> Set<Map.Entry<K, V>> --> Stream<Map.Entry<K, V>>
map.entrySet().stream()

С помощью кнопки on вы можете .filter() по этим записям. Например:

// Stream<Map.Entry<K, V>> --> Stream<Map.Entry<K, V>>
.filter(entry -> entry.getKey() == 1)

И для получения значений из него вы .map():

// Stream<Map.Entry<K, V>> --> Stream<V>
.map(Map.Entry::getValue)

Наконец, вам нужно собрать в List:

// Stream<V> --> List<V>
.collect(Collectors.toList())

Если у вас есть только одна запись, используйте это вместо этого (ПРИМЕЧАНИЕ: этот код предполагает, что есть значение, в противном случае используйте .orElse(), см. javadoc Optional для более подробной информации):

// Stream<V> --> Optional<V> --> V
.findFirst().get()

Ответ 3

Для вашего Q2 на ваш вопрос уже есть ответы. Для вашего Q1 и в целом, когда вы знаете, что ключевая фильтрация должна давать уникальное значение, нет необходимости использовать Streams вообще.

Просто используйте get или getOrDefault, i.e:

List<String> list1 = id1.getOrDefault(1, Collections.emptyList());

Ответ 4

Вы также можете сделать это следующим образом

public Map<Boolean, List<Student>> getpartitionMap(List<Student> studentsList) {

    List<Predicate<Student>> allPredicates = getAllPredicates();
    Predicate<Student> compositePredicate =  allPredicates.stream()
                             .reduce(w -> true, Predicate::and)
     Map<Boolean, List<Student>> studentsMap= studentsList
                .stream()
                .collect(Collectors.partitioningBy(compositePredicate));
    return studentsMap;
}

public List<Student> getValidStudentsList(Map<Boolean, List<Student>> studentsMap) throws Exception {

    List<Student> validStudentsList =  studentsMap.entrySet()
             .stream()
             .filter(p -> p.getKey() == Boolean.TRUE)
             .flatMap(p -> p.getValue().stream())
             .collect(Collectors.toList());

    return validStudentsList;
}

public List<Student> getInValidStudentsList(Map<Boolean, List<Student>> studentsMap) throws Exception {

    List<Student> invalidStudentsList = 
             partionedByPredicate.entrySet()
             .stream()
             .filter(p -> p.getKey() == Boolean.FALSE)
             .flatMap(p -> p.getValue().stream())
             .collect(Collectors.toList());

    return invalidStudentsList;

}

С flatMap вы получите только List<Student> вместо List<List<Student>>.

Спасибо