Java >> Java tutorial >  >> Tag >> HashMap

Kopiering af et HashMap i Java

1. Oversigt

I dette selvstudie vil vi udforske konceptet med en lavvandet kontra dyb kopi af et HashMap sammen med flere teknikker til at kopiere et HashMap i Java.

Vi vil også overveje nogle af de eksterne biblioteker, der kan hjælpe os i specifikke tilfælde.

2. Shallow vs Deep Copies

Lad os først forstå konceptet med overfladiske og dybe kopier i HashMaps .

2.1. Shallow Copy

En overfladisk kopi af et HashMap er et nyt HashMap med tilknytninger til de samme nøgle- og værdiobjekter som det originale HashMap .

For eksempel opretter vi en medarbejder klasse og derefter et kort med Medarbejder instanser som værdier:

public class Employee {
    private String name;

    // constructor, getters and setters
}
HashMap<String, Employee> map = new HashMap<>();
Employee emp1 = new Employee("John");
Employee emp2 = new Employee("Norman");
map.put("emp1", emp1);
map.put("emp2", emp2);

Nu skal vi verificere, at det originale kort og dets lave kopi er forskellige objekter:

HashMap<String, Employee> shallowCopy = // shallow copy implementation
assertThat(shallowCopy).isNotSameAs(map);

Fordi dette er en overfladisk kopi, hvis vi ændrer en medarbejder instansens egenskaber, vil det påvirke både det originale kort og dets overfladiske kopi:

emp1.setFirstName("Johny");
assertThat(shallowCopy.get("emp1")).isEqualTo(map.get("emp1"));

2.2. Deep Copy

En dyb kopi af et HashMap er et nyt HashMap der dybt kopierer alle kortlægninger. Derfor opretter den nye objekter for alle nøgler, værdier og tilknytninger.

Her vil eksplicit ændring af tilknytningerne (nøgleværdier) ikke påvirke den dybe kopi:

HashMap<String, Employee> deepCopy = // deep copy implementation

emp1.setFirstName("Johny");

assertThat(deepCopy.get("emp1")).isNotEqualTo(map.get("emp1"));

3. HashMap API

3.1. Brug af HashMap C instruktør

HashMap ’s parametriserede konstruktør HashMap(Map m) giver en hurtig måde at kopiere et helt kort på:

HashMap<String, Employee> shallowCopy = new HashMap<String, Employee>(originalMap);

3.2. Brug af Map.clone()

Svarende til konstruktøren, HashMap #klon metoden skaber også en hurtig overfladisk kopi:

HashMap<String, Employee> shallowCopy = originalMap.clone();

3.3. Brug af Map.put()

Et HashMap kan nemt kopieres overfladisk ved at iterere over hver post og kalde put() metode på et andet kort:

HashMap<String, Employee> shallowCopy = new HashMap<String, Employee>();
Set<Entry<String, Employee>> entries = originalMap.entrySet();
for (Map.Entry<String, Employee> mapEntry : entries) {
    shallowCopy.put(mapEntry.getKey(), mapEntry.getValue());
}

3.4. Brug af Map.putAll()

I stedet for at gentage alle indgange, kan vi bruge putAll() metode, som lavvandede kopierer alle tilknytningerne i ét trin:

HashMap<String, Employee> shallowCopy = new HashMap<>();
shallowCopy.putAll(originalMap);    

Vi skal bemærke, at put() og putAll() erstatte værdierne, hvis der er en matchende nøgle .

Det er også interessant at bemærke, at hvis vi ser på HashMap 's konstruktør, clone() , og putAll() implementering, vil vi opdage, at de alle bruger den samme interne metode til at kopiere poster — putMapEntries() .

4. Kopierer HashMap Brug af Java 8 Stream API

Vi kan bruge Java 8 Stream API til at oprette en overfladisk kopi af et HashMap :

Set<Entry<String, Employee>> entries = originalMap.entrySet();
HashMap<String, Employee> shallowCopy = (HashMap<String, Employee>) entries.stream()
  .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

5. Google Guava

Ved at bruge Guava Maps kan vi nemt oprette uforanderlige kort sammen med det sorterede og bi-kort. For at lave en uforanderlig, lavvandet kopi af et hvilket som helst af disse kort, kan vi bruge copyOf metode:

Map<String, Employee> map = ImmutableMap.<String, Employee>builder()
  .put("emp1",emp1)
  .put("emp2",emp2)
  .build();
Map<String, Employee> shallowCopy = ImmutableMap.copyOf(map);
    
assertThat(shallowCopy).isSameAs(map);

6. Apache Commons Lang

Nu har Java ingen indbyggede dybe kopi-implementeringer. Så for at lave en dyb kopi kan vi enten tilsidesætte clone() metode eller brug en serialisering-deserialiseringsteknik.

Apache Commons har SerializationUtils med en klone() metode til at skabe en dyb kopi. Til dette skal enhver klasse, der skal inkluderes i dyb kopi, implementere Serialiserbar grænseflade:

public class Employee implements Serializable {
    // implementation details
}

HashMap<String, Employee> deepCopy = SerializationUtils.clone(originalMap);

7. Konklusion

I denne hurtige selvstudie har vi set forskellige teknikker til at kopiere et HashMap i Java, sammen med konceptet med overfladisk og dyb kopi til HashMap s.

Vi undersøgte også nogle af de eksterne biblioteker, der er ret praktiske til at skabe overfladiske og dybe kopier.

Den komplette kildekode for disse implementeringer sammen med enhedstestene er tilgængelige i GitHub-projektet.


Java tag