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

давайте рассмотрим hashmap

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

я вставил некоторые значения в оба hashmap.

Например,

    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 и получить соответствующее значение(список).

например: здесь мой запрос key=1, а вывод должен быть 'list1'

я писал

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

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

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

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

4 ответов


Если вы уверены, что получите не более одного элемента, который прошел фильтр (что гарантируется вашим фильтром), вы можете использовать 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());

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

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

С самого начала, вы можете .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()

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

просто использовать get или getOrDefault, Я.е:

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

вы также можете сделать это

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>>.

спасибо