Prüfsumme einer Klasse?

Fohnbit

Top Contributor
Hallo,

ich habe eine Klasse, die wiederum auf andere Klassen instantiieren und Variablen halten.
Ich serialisiere dann am Ende diese eine Klasse.

Nun muss ich prüfen, ob etwas geändert wurde.
Gibt es eine Prüfsumme oder ähnliches für Klassen?
Damit ich erkennen kann, ob etwas geändert wurde?

Ich muss ein Speichern am Ende meines Programmes einbauen, falls Parameter geändert wurden.

Danke!
 
Man könnte hashCode dafür benutzen, viele Klassen aus java.* haben das sinnvolle Implementierungen. Für eigene Klassen muss man die aber noch selbst implementieren.
 
Das ist aber gefährlich, da können viele Änderungen "übersehen" werden.
hashCode kann für Instanzen mit unterschiedlichen Werten den selben Hash-Wert zurückliefern.
Ändert sich der HashCode, so hat sich auch was an der Instanz geändert, das ist klar, aber damit betrachten man das Problem dennoch aus der falschen Perspektive.
 
Nun, ich habe da keine wirkliche Implementierung gemacht:
Code:
ublic class ProjectSettings implements java.io.Serializable {

    private static final long serialVersionUID = 6475524186910891284L;
    private String location = "";
    private String lblLocation;
    private double latitude, longitude;
    private String projectName = "Projektname";
    private List<Window> windows = new ArrayList<Window>();}
Getter und Setter habe ich rausgenommen, damit es nicht so lang ist.
Speziell die List windows müsste ich überwachen.
 
Hab versucht mich einzulesen:
Code:
@Override
    public int hashCode() {
        ArrayList<Object> objekte = new ArrayList<Object>();
        objekte.add(this.location);
        objekte.add(this.lblLocation);
        objekte.add(this.latitude);
        objekte.add(this.longitude);
        objekte.add(this.projectName);
        objekte.add(this.windows);

        return Objects.hashCode(objekte);

    }

Aber wohl nicht korrekt, da ich immer den selben HashCode bekomme
 
Zeig das mal im Kontext. Also einen Code-Ausschnitt, in dem du hashCode aufrufst und zwischenzeitig auch die Werte für location o.A. änderst.
 
Gerne:

Ich lade die Serialisierung und speichere den HashCode :
Code:
private ProjectSettings project = new ProjectSettings();
private int hashCodeProject;
private Window window;
...
try {
                FileInputStream fileIn = new FileInputStream(filename);
                ObjectInputStream in = new ObjectInputStream(fileIn);
                project = (ProjectSettings) in.readObject();
                hashCodeProject = project.hashCode();
                // projectOriginal = (ProjectSettings) project.clone();
                in.close();
                fileIn.close();

Arbeite dann mit der Instanz (window wird von einem Listbox gefüllt und ist von der Instanzierten Klasse):
Code:
window.lstModelRU_RealCoordinate.addElement(
                    new Point2D.Double(round(coordinateX + window.windowDirectionView, 2), round(coordinateY, 2)));
            window.timeStamp_RU.add(System.currentTimeMillis());
            window.imagesRU.add(makePanelImageScreenshot(imagePane));

project hat sich also geändert, den dieses Objekt in "ProjectSettings" wurde geändert/erweitert:
Code:
private List<Window> windows = new ArrayList<Window>();

Beim beenden prüfe ich dann:
Code:
System.out.println("Project: " + project.hashCode());
                    System.out.println("Ursprung: " + hashCodeProject);

Aber ist immer der selbe Integer Wert
 
Edit:

Der HashCode ändert sich doch, aber nicht immer.
Die Klasse Windows:
Code:
public class Window implements java.io.Serializable {
    Window(String windowName) {
        this.windowName = windowName;
    }

    private static final long serialVersionUID = 1068505166493971108L;

    public String windowName = "Fenster Bezeichnung";
    public String description = "Fenster Beschreibung";

    public DefaultListModel<Point2D> lstModelRU_RealCoordinate = new DefaultListModel<Point2D>();
    public DefaultListModel<Point2D> lstModelLU_RealCoordinate = new DefaultListModel<Point2D>();
    public DefaultListModel<Point2D> lstModelRD_RealCoordinate = new DefaultListModel<Point2D>();
    public DefaultListModel<Point2D> lstModelLD_RealCoordinate = new DefaultListModel<Point2D>();

    public List<Long> timeStamp_RU = new ArrayList<Long>();
    public List<Long> timeStamp_RD = new ArrayList<Long>();
    public List<Long> timeStamp_LU = new ArrayList<Long>();
    public List<Long> timeStamp_LD = new ArrayList<Long>();

    public transient List<BufferedImage> imagesRU = new ArrayList<BufferedImage>();
    public transient List<BufferedImage> imagesLU = new ArrayList<BufferedImage>();
    public transient List<BufferedImage> imagesRD = new ArrayList<BufferedImage>();
    public transient List<BufferedImage> imagesLD = new ArrayList<BufferedImage>();

    public double windowDirectionView = 90;

Wenn ich aus lstModelRU_RealCoordinate, timeStamp_RU, imagesRU einen Eintrag lösche, erhalte ich dennoch denselben HashCode :-(
 
Eventuell noch wichtig:
window zuweisen:
Code:
cmbWindows = new JComboBox<Window>();
            cmbWindows.setFont(new Font("Tahoma", Font.PLAIN, 12));
            cmbWindows.setPreferredSize(new Dimension(150, 20));

            cmbWindows.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    window = (Window) cmbWindows.getSelectedItem();
                    //
                    System.out.println(project.getWindows().get(cmbWindows.getSelectedIndex()));
                    updateForm();
                }
            });
            panel_13.add(cmbWindows);

            // cmbWindows.addItem(project.windows);
            cmbWindows.setModel(new DefaultComboBoxModel(project.getWindows().toArray()));
Beispiel von einem Löschvorgang:
Code:
    int index = lstPointsLU.getSelectedIndex();
            if (index > -1) {
                window.lstModelLU_RealCoordinate.remove(index);
                window.imagesLU.remove(index);
                window.timeStamp_LU.remove(index);
            }
 
Der HashCode ändert sich doch, aber nicht immer.

Vielleicht hast du tatsächlich "Pech" und der HashCode bleibt gleich (das kann passieren, siehe eine meiner vorherigen Anmerkungen).
Jetzt musst du entscheiden: Willst du das Problem, welches hier bei der Verwendung von hashCode auftritt, tatsächlich lösen, oder bist du eher an einer Lösung deines eigentlichen Problems interessiert?

Für letzteres kannst du bei einer Änderungen z.B. ganz einfach ein Flag setzen, welches du abfragen kannst. Beim Laden/Schreiben setzt du es dann wieder zurück. Wo und Wie man das gescheit am Besten macht, dafür hab ich zu wenig einblick in dein Projekt.

Ist ersteres der Fall: Dir fehlt vermutlich schlicht noch eine gescheite Implementierung von hashCode in der Klasse Window.
 
Ich habs mal geändert und für die Einträge in der List einzeln berechnet:
Code:
    @Override
    public int hashCode() {
        ArrayList<Object> objekte = new ArrayList<Object>();
        objekte.add(this.location);
        objekte.add(this.lblLocation);
        objekte.add(this.latitude);
        objekte.add(this.longitude);
        objekte.add(this.projectName);
        for (Window w : this.windows) {
            objekte.add(w.windowName);
            objekte.add(w.description);
            objekte.add(w.lstModelLD_RealCoordinate);
            objekte.add(w.lstModelLU_RealCoordinate);
            objekte.add(w.lstModelRD_RealCoordinate);
            objekte.add(w.lstModelRU_RealCoordinate);
            objekte.add(w.timeStamp_LD);
            objekte.add(w.timeStamp_LU);
            objekte.add(w.timeStamp_RD);
            objekte.add(w.timeStamp_RU);
            objekte.add(w.imagesLD);
            objekte.add(w.imagesLU);
            objekte.add(w.imagesRD);
            objekte.add(w.imagesRU);
            objekte.add(w.windowDirectionView);
            objekte.add(w.plySkySelection_RealCoordinate);
        }
       
        return Objects.hashCode(objekte);

    }

jetzt scheint es zu klappen
 
Die for-Schleife ist da fehl am Platz, damit schaufelst du dir einen Wartungsalptraum. Implementiere hashCode in der Klasse Window und lass deine andere hashCode-Methode (die aus ProjectSettings) ruhig so, wie sie war.
 

Zurück
Oben