2016-08-21 1 views
0

Ich schreibe jetzt ein Programm in Java, das ist wie ein Server. Ich habe eine MemberController, in MemberController es wird Members von der Datenbank oder aus dem Cache (um Prozess zu beschleunigen). Dies ist ein Beispiel dafür, wie es aussieht:Java - ändert sich die Sammlung immer, wenn ich einen Wert bekomme und ändere

public class MemberController { 

    private final TMap<Integer, Member> members; 

    public MemberController() { 
     this.members = new THashMap<>(); 
    } 

    public Member getMemberByID(int id) { 
     if (members.containsKey(id)) { 
      return members.get(id); 
     } 

     // GET DATA FROM DB 
     members.put(ID, MEMBER); 
     return MEMBER; 
    } 

Nun Member enthält ein BadgeController Objekt, das eine TMap für die Abzeichen enthält. Beispiel für Member:

public class Member { 
    // FIELDS OF MEMBER HERE 
    private BadgeController badgeController; 

    public Member(ResultSet set) { 
     // SET FIELDS 
    } 

    public void InitOtherData() { 
     badgeController = new BadgeController(id); 
    } 

    public BadgeController getBadgeController() { 
     return badgeController; 
    } 

Und BadgeController:

public class BadgeController { 

    private final int memberId; 
    private final TMap<String, Badge> badges; 

    public BadgeController(int memberId) { 
     this.memberId = memberId; 
     this.badges = new THashMap<>(); 

     // LOAD FROM DB 
    } 

    public Badge getBadge(String code) { 
     return badges.get(code); 
    } 

Nun, ich war ein paar Dinge fragen (alle tatsächlich beziehen sich auf das gleiche glaube ich):

  1. Wenn ich a Member von members, wie members.get(1), und ich bearbeiten das Objekt, so:

    Mitglied Mitglied = members.get (1); member.setId (1);

Wird das die id innerhalb des TMap auch bearbeiten? Also, wenn ich wieder members.get(1) mache, hat es den aktualisierten Wert?

  1. Wenn ich das Mitglied von oben, und ich einen Wert des Badge ändern, zum Beispiel, das ich tun:

Member member = members.get(1); member.getBadgeController().getBadge('500Members').setActive(true);

Wird dieses Ergebnis in wahr gedruckt werden?

System.out.println(members.get(1).getBadgeController().getBadge('500Members').getActive()); 

Ich hoffe, meine Erklärung ist gut genug. Es ist schwer für mich, es zu erklären. Es tut mir Leid.

+0

Warum testest du es nicht? Das heißt, Sie sind wahrscheinlich Voroptimierung und öffnen eine große Dose Würmer: Sie müssen jetzt mit veralteten Daten im Cache, gleichzeitigem Zugriff auf eine nicht Thread-sichere veränderbare Datenstruktur, usw. umgehen.Benutze einfach die Datenbank, es ist schnell. –

+0

Ich möchte wissen, ob es immer funktioniert. Und es ist komplex zu erklären und komplex zu testen. Es geht viel tiefer als nur das. –

+1

Ja, es funktioniert immer. Keine Datenstruktur wird jemals Kopien Ihrer Objekte erstellen. Sie speichern nur Referenzen. –

Antwort

1

Member member = members.get(1); kopiert nicht das Objekt, sondern macht nur eine Verknüpfung (Referenz). Das Ändern von member wirkt sich auch auf das Element in Ihrem Set aus.

Um eine effektive Kopie zu erstellen, müssen Sie Ihr Objekt von der Cloneable-Schnittstelle übernehmen und die clone()-Methode aufrufen, um eine Kopie zu erhalten.

+0

Und es ist egal wie tief ich gehe? Zum Beispiel, mache ich eine Referenz, dann setze ich den 'BadgeController', dann ändere ich etwas im' Badges' Set, diese Änderungen werden ALLE im ursprünglichen 'members' Set gemacht? –

+0

@ jean-françois-fabre ich denke, dass besser wird, einen Kopierkonstruktor zu verwenden :) – ceph3us

+0

ja, es ist das gleiche Objekt, das Sie behandeln. –

1

Sie müssen DEEP Kopie Objekt von:

  • Implementierung Klon Schnittstelle
  • eine Kopie Konstruktor (einfachste Lösung als Klon)

Beispiele erstellen:

// simple copy constructor 
    public SomerController(SomeController original) { 
     members = orginal.clone(); 
    } 


    // more advanced copy constructor 
    public SomeController(SomeController original) { 
     Set<Map.Entry<String, String>> entries = orginal.members.entrySet(); 
     members = new HashMap<String,Class>(); 
     Iterator<Map.Entry<String, Class>> iterator = entries.iterator(); 
     while(iterator.hasNext()) { 
      Map.Entry<String, String> next = iterator.next(); 
      String key = next.getKey(); 
      // if class contains a collections (maps, arrays) 
      // you need to provide a copy here 
      // ensure to copy whole tree of references 
      Class value next.getValue(); 
      map.put(key,value); 
     } 
    } 
Verwandte Themen