# ArrayList collections.sort() Problem./..



## scaary (24. Februar 2008)

Hallo.
Also, ich habe folgendes problem:

ich Habe eine Liste von punkten, die ich mit Mergesort sortieren muss.

Hierfuer bietet sich ja dieser Befehl an:

collections.sort(Liste);

Problem meinerseits:
Ich muss das ganze nach den X Werten der Punkte sortieren.
Ich weiss aber nicht wie ich das machen soll....
In nem anderen Forum hat mir jetyt schonmal jemand nen Broeckchen hingeworfen von wegen 'Comparator machen'. .... Nun hab ich aber im Internet und allen mir zur verfuegung stehenden Buechern nachgeschlagen, und habs einfach nciht verstanden (um ehrlich zu sein).

Ich moechte gar keine Loesung, ich moechte einfach nur ein bisschen hilfe wie ich sowas mache....

bitte bitte....


----------



## ishino (24. Februar 2008)

Deine Punktklasse muß _Comparable<T>_ implementieren. Ein Beispiel findest Du unten. Wenn _compareTo_ implementiert ist, sollte auch _equals_ so implementiert sein, daß für beliebige x und y gilt: x.comparesTo == 0 -> x.equals. Das ist eine Konvention im Java-Standard, die zwar nicht unbedingt eingehalten werden muß, aber durchaus ihren Sinn hat. Wenn Du die Punktklasse in HashMaps unterbringen willst, mußt Du ggf. auch _hashCode_ entsprechend implementieren.


```
import java.util.ArrayList;
import java.util.Collections;

public class SortExample
{
	private class Sortable implements Comparable<Sortable>
	{
		private int x;

		public Sortable(int x)
		{
			this.x = x;
		}

		@Override
		public int compareTo(Sortable o)
		{
			if (o == null)
			{
				throw new IllegalArgumentException();
			}

			return x - o.x;
		}

		@Override
		public boolean equals(Object obj)
		{
			if (obj == null)
			{
				throw new IllegalArgumentException();
			}

			if (obj instanceof Sortable)
			{
				return x == ((Sortable) obj).x;
			}

			return false;
		}
	}

	public SortExample()
	{
		ArrayList<Sortable> sortables = new ArrayList<Sortable>();
		for (int i = 0; i < 10; i++)
		{
			sortables.add(new Sortable((int) (Math.random() * 100)));
		}

		System.out.println("unsorted sortables");
		for (Sortable s : sortables)
		{
			System.out.println(s.x);
		}

		Collections.sort(sortables);

		System.out.println("sorted sortables");
		for (Sortable s : sortables)
		{
			System.out.println(s.x);
		}
	}

	public static void main(String[] args)
	{
		new SortExample();
	}
}
```


----------



## scaary (24. Februar 2008)

Hi.
Woha, supi, vielen lieben dank fuer die schnelle Antwort ^^

Aber, oki, ich hab vergessen was zu erwaehnen (oder es in deiner Antwort irgendwie nicht gesehen..) Ich hab in meiner Liste Objekte vom Typ Point, die sich aus x und y koordinate zusammensetzen und muss die sortieren. und ich weiss nicht, wie ich den 

Collectio.sort(liste);

auf eine Liste anwenden kann, in der ich den int Wert des Punkts mit

liste.get(ZAHL).x

bekomme. Folglich muesste der z.B. vergleichen ob:

liste.get(3).x < liste.get(4).x und dann entsprechend sortieren.

WIe mach ich das in dem Fall?

Aber schonmal VIELEN DANK


----------



## TheJadix (24. Februar 2008)

Hallo,

Machs doch einfach so :

Du erweiterst die Point-Klasse und zwar in dem du zusätzlich das Compareable-Interface
implementierst.


```
class myPoint extends Point implements Comparable { 

    public int compareTo(Object o) {

        Point theotherpoint = (Point)o;

         // Hier nach deinen Kreterien auswerten und Rückgabewert erzeugen

        // z.B. if (this.x == theotherpoint.x) return 0;

         // return -1 oder 0 oder 1 je nach kleiner oder gleich oder größer !
    }
}
```

Auf diese weise werden die Points sortierbar !

Gruß JAdix


----------



## scaary (24. Februar 2008)

Hi, wow, super, vielen lieben Dank fuer deine Muehe

Ich habs jetzt mal so weit hinbekommen und hab nur noch ein kleines Problem:


```
public class Point{
	double x;
	double y;

	Point (double x, double y){
		this.x = x;
		this.y = y;
	}


	public int compareTo(Object o) {

		Point theotherpoint = (Point)o;


		if(this.x < theotherpoint.x){
			return -1;
		}else if(this.x > theotherpoint.x){
			return 1;
		}else if(this.x == theotherpoint.x){

			if(this.y == theotherpoint.y){
				return 0;	        		 
			}else if(this.y < theotherpoint.y){
				return -1;
			}else if(this.y > theotherpoint.y){
				return 1;

			}
		}
	}
}
```

Ich bekomme die Zeile nicht rein:

```
class myPoint extends Point implements Comparable {
```

Weil meine Klasse schon Point heisst (unser Prof will dass so, geht leider nicht anders).

Kann ich das aendern?

Ahso, und eine Frage noch:

Das
collections.sort(Liste);
greift dann automatisch auf meine Sortierkriterien zu, die ich in der Pointklasse erstellt hab?

Also nochmal, total vielen lieben Dank, das hilft mir echt sehr viel weiter!!


----------



## procurve (24. Februar 2008)

Dann schreibst du einfach


```
class Point implements Comparable { ...
```

bei der vom Prof vorgegebenen Klasse.


----------



## scaary (24. Februar 2008)

Wow, hey, supi, vielen dank nochmals!!

Ich hab noch ne zweite extraklasse, die ich auch sortieren mopechte (mit diesem evrfahren).
Kannst du dir die vllt kurz anschauen und mir meine Fehler sagen?

Danke!


```
public class ShortestDistance implements Comparable{
	double distance;
	double p1x;
	double p1y;
	double p2x;
	double p2y;


	ShortestDistance(double distance, double p1x, double p1y, double p2x, double p2y){
		this.distance = distance;
		this.p1x = p1x;
		this.p1y = p1y;
		this.p2x = p2x;
		this.p2y = p2y;
	}
	
	
	public int compareTo(Object o) {

		int result = 0;
		
		ShortestDistance theotherShortestDistance = (ShortestDistance)o;


		if(this.distance < theotherShortestDistance.distance){
			result = -1;
		}else if(this.distance > theotherShortestDistance.distance){
			result = 1;
		}else if(this.distance == theotherShortestDistance.distance){
			result = 0;
		}		
		return result;
	}
}
```


Achja, eine Frage vllt noch, was genau macht eigentlich dieser teil:


```
ShortestDistance theotherShortestDistance = (ShortestDistance)o;
```

Danke


----------



## TheJadix (24. Februar 2008)

Hallo,

Fehler entdecke ich so auf anhieb keinen, wenn die Objekte mit korrekten distance-Werten gefüttert werden, sollte es klappen !


```
ShortestDistance theotherShortestDistance = (ShortestDistance)o;
```

Das nennt sich "Cast" ! Man erklärt damit das es sich bei dem Object um ein ShortestDistance handelt und so bekommt man zugriff auf
die Felder und Methoden der Klasse ShortestDistance, was vorher beiim Object nicht möglich gewesen wäre !


```
theotherShortestDistance.distance = 0.815; // geht

o.distance = 0.815; // geht nicht ! !
```

Gruß JAdix


----------

