-3
votes

Obtenir et modifier les valeurs de hachage

J'ai un HashMap myHashMap, comme ceci:

myHashMap= myHashMap.entrySet().forEach(p -> p.getValue().setUserType(usernameAndType.get(p))).collect(HashMap::getKey, HashMap::getValue, this::throwIllegalArgumentException, HashMap::new);

La classe UserContact est celle-ci:

myHashMap.entrySet().forEach(p -> p.getValue().setUserType(usernameAndType.get(p)));

Je veux changer tout le userType de mon UserContact en utilisant celui présent dans le hashmap usernameAndType. Pour le faire, j'ai utilisé:

public class UserContact{
    private String username;
    private String userType;
    private String email;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getUserType() {
        return userType;
    }
    public void setUserType(String userType) {
        this.userType = userType;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email= email;
    }
}

Mais cela ne fonctionne pas, car je pense que sans l'enregistrer dans une autre hashmap est inutile. J'ai donc essayé quelque chose comme ça mais je ne peux pas le compiler car j'ai une erreur:

public static void main(String[] args) {
    HashMap<String, UserContact> myHashMap = new HashMap<String, UserContact>(); // first string = username
    fillHasmap(myHashMap); // a method to fill my hashmap
    HashMap<String, String> usernameAndType = new HashMap<String, String>(); // username , userType
    fillUsername(usernameAndType);
    myHashMap.entrySet().forEach(p -> p.getValue().setUserType(usernameAndType.get(p))); // does not work.
}    
    
public static void fillHasmap(HashMap<String, UserContact> myHashMap) {
    for(int i = 0; i<5; i++) {
        UserContact single = new UserContact();
        String username = "stack" + i;
        single.setUsername(username);
        single.setUserType("Client");
        single.setUserEmail("temp" + i + "@drop.me");
        myHashMap.put(username, single);
     }
}

public static void fillUsername(HashMap<String, String> usernameAndType) {
    String[] userType = {"Client","Business"};
    for(int i = 0; i<5; i++) {
        String username = "stack" + i;
        Random r = new Random();
        int a = r.nextInt(2);
        usernameAndType.put(username, usertype[a]);
    }
}

Impossible d'appeler collect (HashMap :: getKey, HashMap :: getValue, this :: throwIllegalArgumentException, HashMap :: new) sur le type primitif void

Je sais que je peux passer le usernameAndType Hashmap à la méthode fillHasmap et obtenir l'élément directement en l'utilisant, mais il existe vraiment un autre moyen de le faire?


0 commentaires

4 Réponses :


1
votes

En supposant que vous ne disposez pas de getters pour le userType , essayez ceci pour créer le hashMap usernameType. Si vous souhaitez modifier la carte de hachage d'origine, consultez mon deuxième exemple.

  • cela diffuse l'entréeSet de votre première carte.
  • crée une nouvelle carte avec la clé et la valeur étant le userType .
  • rappelez-vous que getValue() renvoie un objet UserContact , vous devez donc le déréférencer pour obtenir le userType
for (Entry<String, UserContact> e : myHashMap.entrySet()) {
    UserContact uc = e.getValue();
    uc.setUserType(usernameAndType.get(e.getKey());
}

Si vous avez des getters pour vos champs, vous pouvez changer e->e.getValue().userType en
e->e.getValue().getUserType() ou quel que soit votre nom.

Pour utiliser les informations de la mappe de hachage usernameAndType pour modifier les objets dans myHashMap, procédez comme suit:

Remarque: vous devez utiliser une boucle pour ce faire car il est considéré comme une technique médiocre pour modifier des objets externes à partir d'un flux.

Map<String,String> usernameAndType = myHashMap
             .entrySet()
             .stream()
             .collect(Collectors.toMap(Entry::getKey, e->e.getValue().userType));


0 commentaires

1
votes

Si je comprends correctement le contenu des deux cartes, je pense que ce qui suit fonctionne comme une mise à jour en place:

myHashMap
    .forEach((key, value) -> 
        value.setUserType(usernameAndType.get(key)));

Encore plus simple serait d'utiliser le formulaire suivant:

myHashMap
    .entrySet()
    .forEach(entry ->
        entry.getValue().setUserType(usernameAndType.get(entry.getKey())));


4 commentaires

Comme je l'ai écrit, le myHashMap.entrySet (). ForEach (p -> p.getValue (). SetUserType (usernameAndType.get (p))); ne changez pas le type d'utilisateur


@LizLamperouge - notez que le code équivalent que vous devez utiliser est usernameAndType.get (p.getKey ()) et pas seulement usernameAndType.get (p). Autrement dit, vous devez saisir le nom d'utilisateur KEY, et non pas utiliser l'objet d'entrée de carte.


change p avec p.getKey fonctionne !!!! Mais je ne comprends pas, qu'est-ce que p / entry dans ce cas?


@LizLamperouge itérer dans votre myHashMap à l'aide de foreach produit un Map.Entry <String, UserContact> à chaque fois. Vous avez nommé ce «p». Ainsi p.getValue () renvoie la valeur UserContact et p.getKey () renvoie la clé String. Donc, vous devez obtenir la clé de nom d'utilisateur de la Map.Entry actuelle en utilisant p.getKey (), pour rechercher dans la carte userNameAndType. Utiliser juste p tenterait d'utiliser un UserContact comme clé dans la deuxième carte, d'où l'erreur de compilation que vous auriez rencontrée.



0
votes

Il y a beaucoup de problèmes avec le code:

Premièrement (votre code):

Map<String,String> newMap2 = myHashMap.values().stream()
        .collect(Collectors.toMap(UserContact::getUsername,UserContact::getUserType))

vous appelez collect sur un flux non. Je ne soulignerai pas les erreurs ici, mais en fonction de votre implémentation (du moins comment vous essayez de le faire). Cela aurait dû être suffisant pour changer / muter la valeur de la carte d'origine sans avoir besoin d'en créer une nouvelle.

  Map<String,String> newMap = myHashMap.entrySet()
                          .stream()
                          .map(Map.Entry::getValue)
                          .collect(Collectors.toMap(UserContact::getUsername,UserContact::getUserType));

ici le p est un Map.Entry (clé, valeur), et la valeur est un UserContact donc p.getValue () = UserContact puis appelle un setter vers l'objet

  • Réponse: Peut-être pour une nouvelle carte, vous voulez faire quelque chose comme ceci:

    myHashMap.entrySet().forEach(p -> p.getValue().setUserType("someuserType"));
    

Le raccourci vers l'exemple ci-dessus serait:

myHashMap= myHashMap.entrySet().forEach(p -> p.getValue().setUserType(usernameAndType.get(p))).collect(HashMap::getKey, HashMap::getValue, this::throwIllegalArgumentException, HashMap::new);


0 commentaires

0
votes

Votre exigence de base est de construire un nouveau HashMap? Ou faire muter les valeurs présentes dans le HashMap original?

S'il s'agit de faire muter les valeurs présentes dans HashMap d'origine.

Map<String,UserContact> myHashMapNew = new HashMap<>(myHashMap);

Si vous avez besoin de construire un autre HashMap avec celui mis à jour (Pourquoi?!), Vous pouvez simplement le faire après l'étape précédente.

myHashMap.values().stream().forEach(val -> val.setUserType(usernameAndType.get(val.getUserName())));


1 commentaires

le myHashMap.entrySet (). forEach (p -> p.getValue (). setUserType (usernameAndType.get (p))); ne change pas le type de mon utilisateur ...