web-dev-qa-db-fra.com

Hashmap avec des flux dans Java 8 Des flux pour collecter la valeur de Map

Laissons considérer un hashmap

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

J'ai inséré des valeurs dans les deux hashmap.

Par exemple,

    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) Maintenant, je veux appliquer une condition de filtre sur la clé dans hashmap et récupérer la valeur correspondante (List).

Exemple: ici, ma requête est clé = 1, et le résultat doit être 'list1'

J'ai écrit

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

Mais je ne sais pas comment récupérer une liste en tant que sortie de cette opération de flux.

Q2) Encore une fois, je veux appliquer une condition de filtre sur la clé dans hashmap et récupérer la liste de listes correspondante.

Exemple: ici, ma requête est clé = 1% (la clé peut être 1,10,15) et le résultat doit être 'list1', 'list2', 'list3' (liste de listes).

45
Deepak Shajan

Si vous êtes certain d'obtenir au plus un seul élément ayant réussi le filtre (garanti par votre filtre), vous pouvez utiliser findFirst:

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

Dans le cas général, si le filtre peut correspondre à plusieurs listes, vous pouvez les rassembler dans une liste de listes:

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

Ce que vous devez faire est de créer une Stream sur la Map '_ .entrySet():

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

À partir de là, vous pouvez .filter() sur ces entrées. Par exemple:

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

Et pour en obtenir les valeurs, vous .map():

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

Enfin, vous devez collecter dans un List:

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

Si vous n'avez qu'une entrée, utilisez ceci à la place (NOTE: ce code suppose qu'il existe une valeur; sinon, utilisez .orElse(); voyez le javadoc of Optional pour plus de détails ):

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

Pour votre Q2, il existe déjà des réponses à votre question. Pour votre Q1, et plus généralement lorsque vous savez que le filtrage de la clé doit donner une valeur unique, il n’est pas nécessaire d’utiliser des flux.

Il suffit d'utiliser get ou getOrDefault, c'est-à-dire:

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

Vous pouvez aussi le faire comme ça

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;

}

Avec flatMap vous obtiendrez juste List<Student> au lieu de List<List<Student>>.

Merci

2
Basit