-2

Given a map of Person and Dog:

 LinkedHashMap<Person, Dog> personDogMap = new LinkedHashMap<>();

The classes for Person and Dog:

class Person {
String name;
String id;
int age; 
//getters
}

class Dog {
String name;
int age;
//getters
}

How can I get a Map<Person, List> extracting the duplicate values from this personDogMap

Scenario:

    personDogMap.put(new Person("John", "12345", 23), new Dog("Luke", 5));
    personDogMap.put(new Person("John", "12345", 23), new Dog("Lisa", 7));
    personDogMap.put(new Person("John", "54323", 33), new Dog("Frank", 2));
    personDogMap.put(new Person("Louis", "95223", 23), new Dog("Nick", 12));

In this case the output would be:

{
Person(name=John,
id=12345,
age=23)=[
    Dog(name=Luke,
    age=5),
    Dog(name=Lisa,
    age=7)
],
Person(name=John,
id=54323,
age=33)=[
    Dog(name=Frank,
    age=2)
],
Person(name=Louis,
id=95223,
age=23)=[
    Dog(name=Nick,
    age=12)
]

}

My first try was to: 1 - Check if there's duplicate values in the keyset(the id parameter it's the differentiator) 2 - If so, take this duplicate and add all the values from the duplicate key to the List

But I'm struggling to reduce the duplicate values. Any ideas?

Branis
  • 17
  • 3
  • 1
    Your scenario is flawed. The 4 `personDogMap.put` operations result in only 3 entries in the map since the dog Luke gets overwritten by the dog Lisa. There aren't any multiple entries since one person only has one dog. A `Map` can only hold one dog per person. – f1sh Nov 17 '22 at 00:15
  • Since I'm using new Person in every put operation it returns the "double" entry for John. The first Person John doesn't allocate the same memory that the second. – Branis Nov 17 '22 at 00:20
  • 1
    that's because your Person class does not overwrite `equals` and `hashCode`, which is a requirement for any class that you want to use as a key in a `Map`. You should do that. You need `equals` anyways, how else are you going to check if a Person occurs twice in the Map? – f1sh Nov 17 '22 at 00:24
  • I thought in using the Id parameter for checking Person – Branis Nov 17 '22 at 00:29
  • 3
    A `Map` requires equals and hashCode to be overwritten for the class of the key, otherwise your Map [won't work as intended](https://stackoverflow.com/questions/1894377/understanding-the-workings-of-equals-and-hashcode-in-a-hashmap). – f1sh Nov 17 '22 at 00:31
  • ook, I'll check it out. Tks for helping – Branis Nov 17 '22 at 00:32
  • You're on the right track. But, let me react to this: "Check if there's duplicate values in the keyset". A `HashMap` won't have duplicate keys. Use `get (key)`. If the return is not `null`, update the `List`, and then update the `HashMap` using `put (key, value)`. Since a `LinkedHashMap` IS A `HashMap`, this applies to `LinkedHashMap`. This assumes `equals` and `hashCode` is working for your key class, as already discussed in previous comments. – Old Dog Programmer Nov 17 '22 at 02:03

1 Answers1

0

you can transform your map to the Map<Person, Set<Dog>> later:

private Map<Person, Set<Dog>> transform(Map<Person, Dog> map) {
    return map.entrySet().stream()
        .collect(Collectors.groupingBy(Entry::getKey,
            Collectors.mapping(Entry::getValue, Collectors.toSet())));
}

Or you shout start with Map<Person, Set<Dog>> structure:

 private void initMap() {
    Map<Person, Set<Dog>> personDogs = new LinkedHashMap<>();
    addDog(personDogs, new Person("John", "12345", 23), new Dog("Luke", 5));
    addDog(personDogs, new Person("John", "12345", 23), new Dog("Lisa", 7));
    addDog(personDogs, new Person("John", "54323", 33), new Dog("Frank", 2));
    addDog(personDogs, new Person("Louis", "95223", 23), new Dog("Nick", 12));
  }

  private void addDog(Map<Person, Set<Dog>> personDogs, Person person, Dog dog) {
    personDogs.merge(person,
        Set.of(dog),
        (dogs, dogs2) -> {
          dogs.add(dog);
          return dogs;
        });
  }
Ivan Danilov
  • 41
  • 1
  • 5