# Elemente innerhalb einer ArrayList vergleichen



## Eichelhäer (30. Sep 2018)

Hallo,

Ich hab ne ArrayList  mit Rechtecken (jedes hat ne eigene ID) und möchte diese auf Überschneidungen prüfen. Das Problem ist, dass sich erstens die Rechtecke auch selber prüfen und ich zweitens nicht weiß wie man mittels ID die Rechtecke in einer for-Schleife unterscheidet.

Weiß jemand Rat?

Gruß Eichelhäer


----------



## Thallius (30. Sep 2018)

Nein ich verstehe überhaupt nicht was du sagen willst


----------



## Javinner (30. Sep 2018)

@Eichelhäer 
Schau dir Java-Docs zum Thema "Rectangle" mal an, für dich ist die Methode "
public boolean intersects(Rectangle r)" interessant..


----------



## Robat (30. Sep 2018)

Eichelhäer hat gesagt.:


> mittels ID die Rechtecke in einer for-Schleife unterscheidet.


equals() und hashCode() der Rechteck-Klasse überschreiben und dann in der for-Schleife mit equals auf Gleichheit prüfen.


----------



## Javinner (30. Sep 2018)

Braucht ein Rechteck hier wirklich eine ID?

```
public class RectIntersets
{

    public static void main(String[] args)
    {
        Rectangle[] array = {new Rectangle(0, 0, 10, 10), new Rectangle(0, 0, 15, 15)};
        Rectangle a = new Rectangle(11, 11, 13, 13);
        for(int i = 0; i < array.length; i++)
        {
            if(a.intersects(array[i]))
            {
                System.out.println(array[i].toString() + ", on Place: " + i);
            }
        }
    }
   
}
/** Output */
java.awt.Rectangle[x=0,y=0,width=15,height=15], on Place: 1
```


----------



## Eichelhäer (30. Sep 2018)

Danke ich habs.

Gruß Eichelhäer.


----------



## Javinner (30. Sep 2018)

Eichelhäer hat gesagt.:


> Danke ich habs.
> Gruß Eichelhäer.


Würdest du der Vollständigkeit halber die Antwort auf deine Anfrage veröffentlichen? 
Wäre sehr freundlich


----------



## Eichelhäer (30. Sep 2018)

Damn, hab mich zu früh gefreut.


```
@Override
    public int hashCode() {
        return id;
    }

    @Override
    public boolean equals(Object o) {
        Sprite s = (Sprite) o;
        if(o instanceof Sprite) {
            if(s.id != this.id) {
                return true;
            }
        }
        return false;
    }
```

Und anschließender Prüfung in der for schleife liefert kein true.

Versteh aber nicht warum.

Hier noch kurz der Aufruf:


```
for(int p = 0;p<peasants.size();p++) {
            peasants.get(p).update();
            if(peasants.get(p).equals(peasants.get(p))) {
                if(Tools.collision(peasants.get(p),peasants.get(p))) {
                    peasants.get(p).x = peasants.get(p).getLastX();
                    peasants.get(p).y = peasants.get(p).getLastY();
                   
                }
            }
           
        }
```


----------



## Robat (30. Sep 2018)

Momentan sind bei dir 2 Rechtecke gleich, wenn die ID ungleich ist..


----------



## Eichelhäer (30. Sep 2018)

Hallo nochmal,

ich möchte es so und so funktioniert es, allerdings für 100 Sprites ist das verdammt viel arbeit:


```
if(Tools.collision(peasants.get(0),peasants.get(1))) {
                peasants.get(0).x = peasants.get(0).getLastX();
                peasants.get(0).y = peasants.get(0).getLastY();   
            }
            if(Tools.collision(peasants.get(0),peasants.get(2))) {
                peasants.get(0).x = peasants.get(0).getLastX();
                peasants.get(0).y = peasants.get(0).getLastY();   
            }
            if(Tools.collision(peasants.get(1),peasants.get(2))) {
                peasants.get(1).x = peasants.get(1).getLastX();
                peasants.get(1).y = peasants.get(1).getLastY();   
            }
            if(Tools.collision(peasants.get(1),peasants.get(0))) {
                peasants.get(1).x = peasants.get(1).getLastX();
                peasants.get(1).y = peasants.get(1).getLastY();   
            }
            if(Tools.collision(peasants.get(2),peasants.get(1))) {
                peasants.get(2).x = peasants.get(2).getLastX();
                peasants.get(2).y = peasants.get(2).getLastY();   
            }
            if(Tools.collision(peasants.get(2),peasants.get(0))) {
                peasants.get(2).x = peasants.get(2).getLastX();
                peasants.get(2).y = peasants.get(2).getLastY();   
            }
```


----------



## mrBrown (30. Sep 2018)

Javinner hat gesagt.:


> @Eichelhäer
> Schau dir Java-Docs zum Thema "Rectangle" mal an, für dich ist die Methode "
> public boolean intersects(Rectangle r)" interessant..


Ich würde von Rechteck nicht auf Rectangle schließen, das ist oftmals ne ungeeignete Klasse 

Bei der ID Stimm ich dir aber zu, die ist für sowas wie Rechtecke Unsinn (außer für die awt-Rectangle-Klasse  )



Eichelhäer hat gesagt.:


> Hallo nochmal,
> 
> ich möchte es so und so funktioniert es, allerdings für 100 Sprites ist das verdammt viel arbeit:
> 
> ...


Überleg doch mal, wenn man die Zahlen durch eine Schleife generieren kann...


In deiner equals-Methode castest du btw, bevor du prüfst, ob es die passende Klasse ist - das solltest du andersrum machen.


----------



## Eichelhäer (30. Sep 2018)

Ok ich denke ich bekomms mit der Generierung der Zahlen irgendwie hin. Man muss ja nur die Regel dahinter verstehen.


----------



## mihe7 (30. Sep 2018)

Eichelhäer hat gesagt.:


> ich möchte es so und so funktioniert es, allerdings für 100 Sprites ist das verdammt viel arbeit:


Wenn die Überschneidungen aller Rechtecke gefunden werden sollen, dann macht man so was mit einem Sweep.


----------



## Javinner (30. Sep 2018)

mrBrown hat gesagt.:


> Ich würde von Rechteck nicht auf Rectangle schließen


Da aber Rectangle zu Deutsch Rechteck heißt und ein Rechteck als solcher angesehen wird, wenn alle seine Winkel rechte Winkel sind, auch die "Rechtecke", welche im Volksmund als Quadrate bekannt sind, sehe ich persönlich da kein wirklichen Unterschied. So, jetzt aber genug geklugscheißert, Zeit fürs Bett, in dem Sinn schönen Abend noch


----------



## mrBrown (30. Sep 2018)

Javinner hat gesagt.:


> Da aber Rectangle zu Deutsch Rechteck heißt und ein Rechteck als solcher angesehen wird, wenn alle seine Winkel rechte Winkel sind, auch die "Rechtecke", welche im Volksmund als Quadrate bekannt sind, sehe ich persönlich da kein wirklichen Unterschied.


Okay, mein Satz in genauer: Rechteck nicht auf *java.awt.*Rectangle schließen


----------



## mrBrown (30. Sep 2018)

Eichelhäer hat gesagt.:


> Ok ich denke ich bekomms mit der Generierung der Zahlen irgendwie hin. Man muss ja nur die Regel dahinter verstehen.



Nur so als Tipp: zwei for-schleifen ineinander...


----------



## MoxxiManagarm (1. Okt 2018)

> if(Tools.collision(peasants.get(0),peasants.get(1))) {
> peasants.get(0).x = peasants.get(0).getLastX();
> peasants.get(0).y = peasants.get(0).getLastY();
> }
> ...



Ohne deine Semantik zu kennen macht das für mich perse nicht wirklich Sinn zu fragen ob A intersects B + B intersects A



> if(peasants.get(p).equals(peasants.get(p))) {



Bitte was?


----------



## Eichelhäer (3. Okt 2018)

Naja, ich hab halt ne List mit allen Sprites und möchte die unterscheiden können. Das Problem ist halt das bei meinem Aufruf sich die Rechtecke selbst auf intersects prüfen und genau das möchte ich nicht. Stattdessen soll jedes Rechteck in der Liste als einziges angesehen werden.

Es macht schon Sinn, denn gehardcodet geht's ja.


----------



## Javinner (3. Okt 2018)

Eichelhäer hat gesagt.:


> Stattdessen soll jedes Rechteck in der Liste als einziges angesehen werden


Was meinst du denn damit?


----------



## Eichelhäer (3. Okt 2018)

Jedes Objekt in einer Liste unterscheidet sich nur durch seine ID.

Wenn ich aber mit equals prüfe zwei Rectecke sind verschieden wenn die id verschieden ist geht's auch nicht. Kein Plan warum?


----------



## Javinner (3. Okt 2018)

@Eichelhäer 
Prüfe doch, wie bereits erwähnt, mit hashcode().  Alternativ kann man noch mit compareTo(Object obj) prüfen, dazu musst du aber das Interface Comporable<T> implementieren.

```
public class Beispiel
{
    /** A */
    public static void main(String[] args)
    {
        int position_in_x = 10;
        int position_in_y = 10;
        Rechteck a = new Rechteck(position_in_x, position_in_y, 10, 10);
        Rechteck b = new Rechteck(position_in_x, position_in_y, 10, 10);
        System.out.println(a.compareTo(b));
        System.out.println(a.equals(b));
    }
/** Output */
0
true
}
```


```
public class Beispiel
{
    /** B */
    public static void main(String[] args)
    {
        int position_in_x = 10;
        int position_in_y = 10;
        Rechteck a = new Rechteck(position_in_x, position_in_y, 10, 10);
        Rechteck b = new Rechteck(position_in_x, position_in_y, 11, 10);
        System.out.println(a.compareTo(b));
        System.out.println(a.equals(b));
    }
/** Output */
-1
false
}
```

Wie willst du denn die Rechtecke prüfen, bzw. den die selbe ID zuweisen, wenn diese die gleichen Positionen und Maße haben?


----------



## temi (3. Okt 2018)

Eichelhäer hat gesagt.:


> Es macht schon Sinn, denn gehardcodet geht's ja.


Nur weil etwas geht, muss es nicht sinnvoll sein...



Eichelhäer hat gesagt.:


> Jedes Objekt in einer Liste unterscheidet sich nur durch seine ID.


Naja, die Positionen werden wohl auch nicht identisch sein, sonst würdest du ja nicht auf Überschneidung prüfen wollen...


----------



## thecain (3. Okt 2018)

Überschreib doch einfach equals und überprüfe dort die Id. Comparable zu überschreiben dürfte nicht nötig sein.


----------



## Eichelhäer (3. Okt 2018)

HH,
Ok.
Bleiben wir bei den Rechtecken. Auf einem Spielfeld sind größengleiche Rechtecke an verschiedenen Positionen verteilt. Klickt man auf ein Rechteck, kann man es mit den Pfeiltasten bewegen. ich möchte halt nicht hundert einzelne Rechtecke per Hand eingeben und diese dann per Hand auf intersects prüfen was ja eig. gehen sollte (erstmal unabhängig von dem eigtl. sin ddahinter). Diese Rechtecke möchte ich alle in ner liste halten und eben mit möglichst wenig aufwand auf intersects prüfen. Wie gesagt gehardcodet geht ja.


----------



## Javinner (3. Okt 2018)

Eichelhäer hat gesagt.:


> Auf einem Spielfeld sind größengleiche Rechtecke an verschiedenen Positionen verteilt


Wenn die Rechtecke dann in einer Liste aufgeführt sind, dann ist es doch recht einfach, das gerade angeklickte Rechteck mit allen Rechtecken der Liste per Schleife zu vergleichen?!


----------



## temi (3. Okt 2018)

Eichelhäer hat gesagt.:


> Klickt man auf ein Rechteck, kann man es mit den Pfeiltasten bewegen.


Dann musst du ja schon mal nicht jedes Rechteck mit jedem anderen Rechteck vergleichen, sondern "nur" das eine, das sich bewegt, mit allen anderen.

`peasants.intersectsWith(movingPeasant)`

Die Methode "intersectsWith" musst du dir halt für die Klasse "Peasants" (die die Liste enthält) noch schreiben. Darin gehst du in einer Schleife einfach durch die Liste und vergleichst.


```
class Peasants {

    List<Peasant> peasants;

    public boolean intersectsWith(Peasant p) {
        for (Peasant peasant : peasants) {
            // ...
        }
    }
}
```


----------



## Eichelhäer (3. Okt 2018)

Jo. Ok.
Erstmal danke dafür. Ich denke ich habs soweit kapiert.
Allerdings hab ich jetzt ohne equals und hasCode zu überschreiben einfach direkt die ids verglichen in den schleifen und bekomm genau die werte die ich für die Bestimmung haben wollte (siehe hardcodet Variante die ich postete).

Hier kurz die schleifen:


```
for(int i = 0;i<peasants.size();i++) {
            for(int j = 0;j<peasants.size();j++) {
                peasants.get(i).update();
                if(peasants.get(i).id!=peasants.get(j).id) {
                    System.out.println(peasants.get(i).id + "    " + peasants.get(j).id);
                    if(Tools.pixelCollision(peasants.get(peasants.get(i).id),peasants.get(peasants.get(j).id))) {
                        peasants.get(peasants.get(i).id).x = peasants.get(peasants.get(i).id).getLastX();
                        peasants.get(peasants.get(i).id).y = peasants.get(peasants.get(i).id).getLastY();
                        System.out.println(true);
                    }
                }
            }
        }
```

Die Kollision wird zwar erkannt, aber lastX greift nicht mehr.
Liegt das an der Laufzeit?


----------



## temi (3. Okt 2018)

Eichelhäer hat gesagt.:


> Ich denke ich habs soweit kapiert.


Hm, gemacht hast du aber etwas anderes...


----------



## Eichelhäer (3. Okt 2018)

Ja das hatte ich auch noch vorher. Eigentlich nicht wichtig hätte mich nur interessiert


----------



## temi (3. Okt 2018)

Eichelhäer hat gesagt.:


> Ja das hatte ich auch noch vorher. Eigentlich nicht wichtig hätte mich nur interessiert





Eichelhäer hat gesagt.:


> peasants.get(peasants.get(i).id).x


Du versuchst hier als Index für den Zugriff auf "peasants" die "id" zu verwenden. Das kann funktionieren, aber nur solange, wie der Index tatsächlich mit der "id" übereinstimmt, ansonsten greifst du auf das falsche Listenelement zu.


----------



## Eichelhäer (3. Okt 2018)

HHHHHHH,
Ich habs. Zu blöd wenn man update gleichzeitig mit aufruft.

Hier der Code:

```
for(int i = 0;i<peasants.size();i++) {
            peasants.get(i).update();
        }
       
        for(int i = 0;i<peasants.size();i++) {
            for(int j = 0;j<peasants.size();j++) {
                if(peasants.get(i).id!=peasants.get(j).id) {
                    if(Tools.pixelCollision(peasants.get(peasants.get(i).id),peasants.get(peasants.get(j).id))) {
                        peasants.get(peasants.get(i).id).x = peasants.get(peasants.get(i).id).getLastX();
                        peasants.get(peasants.get(i).id).y = peasants.get(peasants.get(i).id).getLastY();
                    }
                }
            }
        }
```

update Methode separat und gut is.

Vielen dank trotzdem an alle Thema hiermit geschlossen mir reicht das so. Auch wenn mich das mit hashCode und equals überschreiben interessiert hat. 

Gruß Eichelhäer


----------



## mrBrown (3. Okt 2018)

Sicher, dass das Benutzen der ID als Index so richtig ist?


----------



## Eichelhäer (7. Okt 2018)

Hallo mal wieder,
das mit der ID war doch keine gute Idee. Damit stößt man schnell an Grenzen für weitere Implementationen.
Ich habe ne Klasse die von Rectangle erbt. Wie muss ich denn die hashCode() bzw. die equals Methode überschreiben?
Also meine versuche schlugen fehl.


----------



## mihe7 (7. Okt 2018)

Schreib doch einfach mal, was Du jetzt eigentlich genau haben willst. Einmal schreibst Du von Rechtecken, dann kasperst Du mit irgendwelchen Sprites herum, dann geht es einmal um Überschneidungen aller Rechtecke, dann wieder nur von einem mit allen anderen usw. usw. Jetzt von Rectangle abgeleitete Klasse... Das kann doch nicht sein, dass man für ein (scheinbar) triviales Problem mittlerweile 34 Kommentare braucht und immer noch nicht weiß, was nun eigentlich rauskommen soll.


----------

