J'ai quelques Map
objets qui sont calées par le même type K
avec des valeurs différentes tapées V1...VN
, qui, pour le but de cette question ne partagent pas supertype *:Comment filtrer et collecter efficacement une carte résultante avec des valeurs de carte dérivées différemment à partir de quelques cartes?
Map<K, V1> kv1
Map<K, V2> kv2
Map<K, V3> kv3
...
Map<K, VN> kvN
Je dois créer une carte résultant en filtrant chacune de ces cartes différemment, puis en utilisant un 'mappeur de valeurs' pour mapper les valeurs V1...VN
à des valeurs V
communément typées (c'est-à-dire Function<? super Entry<K, VN>, ? extends V>
) sur ces cartes. En tant que tel, j'ai la méthode d'assistance static
suivante pour effectuer les deux premières étapes:
public static <K, VN, V> Map<K, V> filterAndMapValue(final Map<K, VN> map,
final Predicate<? super Entry<K, VN>> predicate,
final Function<? super Entry<K, VN>, ? extends V> mapper) {
return map.entrySet().stream().filter(predicate)
.collect(Collectors.toMap(Entry::getKey, mapper));
}
Mes dossiers en cours d'utilisation en font de supposer que seulement après le filtrage sur chaque carte me donner des clés distinctes pour la final Map
objet (il peut y avoir les mêmes clés utilisées dans chaque carte), mais dans le cas où cela ne se vérifie pas dans le futur, je sais que je peux fournir une expression supplémentaire mergeFunction
à Collectors.toMap(Function, Function, BinaryOperator)
pour gérer cela correctement.
Le code final se lit maintenant quelque chose comme ce qui suit:
Map<K,V> result = filterAndMapValue(kv1, predicateForKV1, mapV1toV);
result.putAll(filterAndMapValue(kv2, predicateForKV2, mapV2toV));
result.putAll(filterAndMapValue(kv2, predicateForKV3, mapV3toV));
...
result.putAll(filterAndMapValue(kvN, predicateForKVN, mapVNtoV));
// do something with result
Question: Y at-il un moyen plus efficace de le faire? Cela ressemble à un autre cas de réduction de données (cartes filtrées) dans une collection finale (Map
) qui nécessite des invocations de réduction différentes (la partie de mappage de valeur), et je ne suis pas sûr que j'approche la bonne façon.
* - Si c'est le cas, j'imagine que V1...VN
peut implémenter une méthode parente, par exemple V convertToV(Object... possiblyAdditionalArgumentsToPerformTheConversion)
, de sorte que mon problème soit réduit à l'application de différentes formes de filtrage pour différentes cartes. S'il y a aussi une solution plus simple étant donné cette hypothèse alternative, n'hésitez pas à le mentionner aussi.
Que diriez-vous de créer un objet pour contenir toutes les valeurs V1 ... VN et utiliser une seule carte? – BobTheBuilder
@BobTheBuilder voulez-vous dire collecter toutes les valeurs des cartes au début? Le mappage des valeurs est fait différemment pour différents types, et à la fin, j'ai aussi besoin de connaître les mappages des touches pour les nouvelles valeurs 'V' ... J'ai également fourni une modification pour indiquer que les 'clés résultantes uniques 'est seulement applicable * après * le filtrage sur les cartes, de sorte que les cartes originales peuvent avoir les mêmes clés. Je ne serais pas en mesure de faire une «carte» dans ce sens. J'espère que ça répond à ta question. –
Ce que je veux dire est de créer une classe MyValues qui a des champs V1..VN.Si vous utilisez cette classe, MyValues contient toutes les valeurs pour chaque clé dans un objet et il est plus facile à gérer et à maintenir – BobTheBuilder