Discussion:
Mehrdimensionales Array sortieren
(zu alt für eine Antwort)
HeidiWeber
2006-02-24 18:33:16 UTC
Permalink
Hallo

ich möchte eine sequentielle Datei mit folgendem Aufbau in ein Array
einlese:

Aufbau der Datei:
4;6;d;1
9;x;4;s
7;s;2;2
4;o;3;1
e;t;s;3
8;2;1;0

Dazu habe ich eine Klasse für ein Array erstellt:


public class InputArray {
private String wert1;
private String wert2;
private String wert3;
private String wert4;

public void setWert1(String wert1) {
this.wert1 = wert1;
}

public String getWert1() {
return wert1;
}

//Für die anderen Variablen entsprechend

}


In der Main()-Klasse wird das Array befüllt:

InputArray einlesen[] = new InputArray[50];

einlesen[0] = new InputArray();

for (i=0;i<50;i++) {
einlesen[i] = new InputArray();
einlesen[i].setWert1("a" + i);
einlesen[i].setWert2("b" + i);
einlesen[i].setWert3("c" + i);
}


Jetzt soll das Array nach dem Wert1 und dem Wert3 aufsteigen bzw.
absteigend sortiert werden können. Danach soll das Array z.B. auf dem
Bildschirm ausgegeben werden.

SOERTIEREN(einlesen NACH WERT1 ASC; WERT3 DSC);

for (i=0;i<50;i++) {
System.out.println(einlesen[i].SORTIERT);
}

Frage 1:
Gibt es solch eine Funktion? Oder muss man sowas selbst programmieren?
Hoffentlich nicht...

Frage 2:
Wenn man solch eine Datei in ein Array einlesen möchte, macht man das
dann so mit einem Array? Passt das so? Oder nimmt man dazu "vorhandene
Array-Klassen" wie z.B. ArayList?

Vielen Dank
cu
Heidi
Carsten Wanke
2006-02-24 20:03:35 UTC
Permalink
Hallo Heidi,
Post by HeidiWeber
ich möchte eine sequentielle Datei mit folgendem Aufbau in ein Array
4;6;d;1
9;x;4;s
7;s;2;2
4;o;3;1
e;t;s;3
8;2;1;0
public class InputArray {
private String wert1;
private String wert2;
private String wert3;
private String wert4;
public void setWert1(String wert1) {
this.wert1 = wert1;
}
public String getWert1() {
return wert1;
}
//Für die anderen Variablen entsprechend
}
InputArray einlesen[] = new InputArray[50];
einlesen[0] = new InputArray();
for (i=0;i<50;i++) {
einlesen[i] = new InputArray();
einlesen[i].setWert1("a" + i);
einlesen[i].setWert2("b" + i);
einlesen[i].setWert3("c" + i);
}
Jetzt soll das Array nach dem Wert1 und dem Wert3 aufsteigen bzw.
absteigend sortiert werden können. Danach soll das Array z.B. auf dem
Bildschirm ausgegeben werden.
SOERTIEREN(einlesen NACH WERT1 ASC; WERT3 DSC);
for (i=0;i<50;i++) {
System.out.println(einlesen[i].SORTIERT);
}
Gibt es solch eine Funktion? Oder muss man sowas selbst programmieren?
Hoffentlich nicht...
Dir hilft vielleicht:

Arrays.sort(InputArray[] a, Comparator<InputArray> c)

Eine Klasse, die Comparator<InputArray> implementiert, mußt Du selbst
schreiben, sie beeinhaltet eine Methode

int compare(InputArray o1, InputArray o2)

mittels der Du die Sortierung festlegen kannst.

Gruß, Carsten
HeidiWeber
2006-02-25 21:14:33 UTC
Permalink
Hallo Carsten,

kanst du mir bitte weiterhelfen? Ich bekomme das nicht hin:(

Die ganzen Beispiele zu Comparator funzen ja alle, aber wenn ich die
Beispiele bei mir einbaue, so kommt jedesmal:
Exception in thread "main" java.lang.ClassCastException:
de.arraysort.InputArray
at de.arraysort.MyComparator.compare(MyComparator.java:8)
at java.util.Arrays.mergeSort(Unknown Source)
...


Liegt das daran, dass das eine Klasse ist, die sortiert werden soll?
Vielen Dank
cu
Heidi
Alfred
2006-02-26 07:25:15 UTC
Permalink
Post by HeidiWeber
Hallo Carsten,
kanst du mir bitte weiterhelfen? Ich bekomme das nicht hin:(
Die ganzen Beispiele zu Comparator funzen ja alle, aber wenn ich die
de.arraysort.InputArray
at de.arraysort.MyComparator.compare(MyComparator.java:8)
at java.util.Arrays.mergeSort(Unknown Source)
...
Liegt das daran, dass das eine Klasse ist, die sortiert werden soll?
Eine Klasse selbst wird nicht sortiert. Du willst eine Sammlung
von Objekten der gleichen Klasse sortieren, nach wert1 aufsteigend
und wert2 absteigend.

Also erstmal die Klasse, die eine Zeile darstellt:

public class MyRecord {
private String wert1, wert2, wert3, wert4;

public MyRecord(
String wert1, String wert2, String wert3, String wert4)
{
this.wert1 = wert1;
this.wert2 = wert2;
this.wert3 = wert3;
this.wert4 = wert4;
}

public String toString () {
StringBuffer buf = new StringBuffer();
buf.append(wert1).append(';').append(wert2).append(';');
buf.append(wert3).append(';').append(wert4);
return buf.toString();
}
public String getWert1() { return wert1; }
public String getWert2() { return wert2; }
public String getWert3() { return wert3; }
public String getWert4() { return wert4; }

public static Comparator getComparator () {
return new Comparator () {
public int compare(Object o1, Object o2) {
MyRecord r1 = (MyRecord)o1;
MyRecord r2 = (MyRecord)o2;
String s11 = r1.getWert1();
String s13 = r1.getWert3();
String s21 = r2.getWert1();
String s23 = r2.getWert3();
//--> erstmal nach wert1 (asc) sortieren
int result = s11.compareTo(s21);
switch (result) {
//--> bei Gleichheit weitere Sortierung
//--> nach wert3 (desc)
case 0: return 0 | s23.compareTo(s13);
default: return result;
}
}
};
}
}

Und nun noch testen:

import java.util.ArrayList;
import java.util.Iterator;

public class Test {
public static void main (String[] args) {
ArrayList list = new ArrayList();
fillTestData(list);
print(list);
System.out.println("--------------------------");
Collections.sort(list, MyRecord.getComparator());
print(list);
System.out.println("--------------------------");
}

private static void print (ArrayList list) {
MyRecord record = null;
for (Iterator iter = list.iterator(); iter.hasNext(); ) {
record = (MyRecord)iter.next();
System.out.println(record);
}
}
private static void fillTestData (ArrayList list) {
list.add(new MyRecord("abc", "o", "123", "1"));
list.add(new MyRecord("abc", "o", "456", "1"));
list.add(new MyRecord("abc", "o", "ABC", "1"));
list.add(new MyRecord("abc", "o", "DEF", "1"));
list.add(new MyRecord("abc", "o", "GHI", "1"));
list.add(new MyRecord("4", "6", "d", "1"));
list.add(new MyRecord("9", "x", "4", "s"));
list.add(new MyRecord("7", "s", "2", "2"));
list.add(new MyRecord("4", "o", "3", "1"));
list.add(new MyRecord("e", "t", "s", "3"));
list.add(new MyRecord("8", "2", "1", "0"));
list.add(new MyRecord("4", "o", "a", "1"));
list.add(new MyRecord("4", "o", "9", "1"));
list.add(new MyRecord("8", "2", "5", "0"));
list.add(new MyRecord("4", "o", "8", "1"));
list.add(new MyRecord("4", "o", "abc", "1"));
list.add(new MyRecord("4", "o", "def", "1"));
list.add(new MyRecord("abc", "o", "abc", "1"));
list.add(new MyRecord("abc", "o", "def", "1"));
list.add(new MyRecord("abc", "o", "ghi", "1"));
}
}

Alfred
Ps: ascii(Ziffer) < ascii(Grossbuchstabe) < ascii(Kleinbuchstabe)
Sebastian Baechle
2006-02-26 09:12:18 UTC
Permalink
Post by Alfred
public static Comparator getComparator () {
return new Comparator () {
public int compare(Object o1, Object o2) {
MyRecord r1 = (MyRecord)o1;
MyRecord r2 = (MyRecord)o2;
String s11 = r1.getWert1();
String s13 = r1.getWert3();
String s21 = r2.getWert1();
String s23 = r2.getWert3();
//--> erstmal nach wert1 (asc) sortieren
int result = s11.compareTo(s21);
switch (result) {
//--> bei Gleichheit weitere Sortierung
//--> nach wert3 (desc)
case 0: return 0 | s23.compareTo(s13);
default: return result;
}
}
};
}
Also ich würde den Comparator entweder extern oder die
Klasse selbst Comparable implementieren lassen.

Ersteres wenn ich evtl. auch andere Sortierungen unterstützen
möchte und die zweite Variante, wenn mir eine Sortierung
reicht.
Alfred
2006-02-27 18:16:38 UTC
Permalink
Post by Sebastian Baechle
Also ich würde den Comparator entweder extern oder die
Klasse selbst Comparable implementieren lassen.
Ersteres wenn ich evtl. auch andere Sortierungen unterstützen
möchte und die zweite Variante, wenn mir eine Sortierung
reicht.
Schön gesagt.

Alfred
HeidiWeber
2006-03-06 18:06:57 UTC
Permalink
Hallo

ich habe jetzt bei der Klasse Filter den Comparator implementiert. Dies
sieht jetzt so aus:

public class Filter implements Comparator{

private String sFilterNr;
private String sStelleVon;
private String sStelleBis;
private String sWbVon;
private String sWbBis;
private String sProz;

public Filter(){
}

public Filter(
String sFilterNr, String sStelleVon,
String sStelleBis, String sWbVon,
String sWbBis, String sProz){

this.sFilterNr = sFilterNr;
this.sStelleVon = sStelleVon;
this.sStelleBis = sStelleBis;
this.sWbVon = sWbVon;
this.sWbBis = sWbBis;
this.sProz = sProz;
}

public String getSFilterNr() {
return sFilterNr;
}
public String getSStelleBis() {
return sStelleBis;
}
public String getSStelleVon() {
return sStelleVon;
}
public String getSWbBis() {
return sWbBis;
}
public String getSWbVon() {
return sWbVon;
}
public String getSProz() {
return sProz;
}

public int compare(Object o1, Object o2) {
Filter f1 = (Filter)o1;
Filter f2 = (Filter)o2;
String s11 = f1.getSStelleVon();
String s13 = f1.getSStelleBis();
String s21 = f2.getSStelleVon();
String s23 = f2.getSStelleBis();
//--> ermal nach StelleVon (asc) sortieren
int result = s11.compareTo(s21);
switch (result){
//--> bei Gleichheit weitere Sortierung
//--> nach WbVon (desc)
case 0: return 0 | s23.compareTo(s13);
default: return result;

}
}

}


In der Main-Routine mache ich folgendes:

ArrayList list = new ArrayList();
list.add(new Filter(asInpSplitt[0], asInpSplitt[1], asInpSplitt[2],
asInpSplitt[4], asInpSplitt[5],
asInpSplitt[6]));

//ArrayList unsortiert ausgeben:
Filter record = null;

for (Iterator iter = list.iterator(); iter.hasNext(); ) {
record = (Filter)iter.next();
System.out.println(record.getSStelleVon());
}

Jetzt wieder mein Problem: Wie kann ich sortieren?
Wie kann/muss ich die Methode compare aufrufen? Ich habe doch in der
Main gar kein Objekt von Filter, das ich übergeben kann? Ist der
Ansatz überhaupt richtig?

Kann mir bitte jemand weiterhelfen?
Vielen Dank
cu
Heidi
Alfred
2006-03-06 21:00:44 UTC
Permalink
Post by HeidiWeber
Hallo
ich habe jetzt bei der Klasse Filter den Comparator implementiert. Dies
public class Filter implements Comparator{
private String sFilterNr;
private String sStelleVon;
private String sStelleBis;
private String sWbVon;
private String sWbBis;
private String sProz;
public Filter(){
}
public Filter(
String sFilterNr, String sStelleVon,
String sStelleBis, String sWbVon,
String sWbBis, String sProz){
this.sFilterNr = sFilterNr;
this.sStelleVon = sStelleVon;
this.sStelleBis = sStelleBis;
this.sWbVon = sWbVon;
this.sWbBis = sWbBis;
this.sProz = sProz;
}
public String getSFilterNr() {
return sFilterNr;
}
public String getSStelleBis() {
return sStelleBis;
}
public String getSStelleVon() {
return sStelleVon;
}
public String getSWbBis() {
return sWbBis;
}
public String getSWbVon() {
return sWbVon;
}
public String getSProz() {
return sProz;
}
public int compare(Object o1, Object o2) {
Filter f1 = (Filter)o1;
Filter f2 = (Filter)o2;
String s11 = f1.getSStelleVon();
String s13 = f1.getSStelleBis();
String s21 = f2.getSStelleVon();
String s23 = f2.getSStelleBis();
//--> ermal nach StelleVon (asc) sortieren
int result = s11.compareTo(s21);
switch (result){
//--> bei Gleichheit weitere Sortierung
//--> nach WbVon (desc)
case 0: return 0 | s23.compareTo(s13);
default: return result;
}
}
}
ArrayList list = new ArrayList();
list.add(new Filter(asInpSplitt[0], asInpSplitt[1], asInpSplitt[2],
asInpSplitt[4], asInpSplitt[5],
asInpSplitt[6]));
Filter record = null;
for (Iterator iter = list.iterator(); iter.hasNext(); ) {
record = (Filter)iter.next();
System.out.println(record.getSStelleVon());
}
Jetzt wieder mein Problem: Wie kann ich sortieren?
Wie kann/muss ich die Methode compare aufrufen? Ich habe doch in der
Main gar kein Objekt von Filter, das ich übergeben kann? Ist der
Ansatz überhaupt richtig?
1.Implementiere nicht Comparator sondern Comparable
und implementiere die Methode compareTo(Object o)

public class Filter implements Comparable {
....
public int compareTo(Object o) {
//--> Achtung nur Beispiel, ich würde eher zu
//--> einer IllegalArgumentException neigen
if (o == null) return 0;
if (o.getClass() != Filter.class) return 0;

Filter other = (Filter)o;
String stelleVon1 = this.getSStelleVon();
String wbVon1 = this.getSWbVon();
String stelleVon2 = other.getSStelleVon();
String wbVon2 = other.getSWbVon();
//--> erstmal nach StelleVon (asc) sortieren
int result = stelleVon1.compareTo(stelleVon2);
switch (result) {
//--> bei Gleichheit weitere Sortierung
//--> nach WbVon (desc)
case 0: return 0 | wbVon2.compareTo(wbVon1);
default: return result;
}
}}

2.Befüllen:
ArrayList list = new ArrayList();
list.add(new Filter(...));
list.add(new Filter(...));
etc.pp.

3.Sortieren:
Collections.sort(list);
//--> weil deine Klasse Comparable implementiert, wird
//--> _deine_ compareTo-Methode implizit aufgerufen
//--> das macht die VM also von ganz allein, wenn sort()
//--> ausgeführt wird

4.Ausgeben:
deine for-Schleife

Alfred
Ps: ich würde bei einer eigenen Comparator-Klasse bleiben
HeidiWeber
2006-03-07 15:06:09 UTC
Permalink
Hallo Alfred,

Vielen Dank für deine extreme Geduld.
Da du eine eigene Comparator-Klasse erstellen würdest, habe ich das
folgendermasen ausprobiert:

Erstellen einer eigenen Klasse Vergleichen:

public class Vergleichen {

public static Vergleichen getComparator () {
return new Vergleichen () {
public int compare(Object o1, Object o2) {

Filter f1 = (Filter)o1;
Filter f2 = (Filter)o2;
String s11 = f1.getSStelleVon();
String s13 = f1.getSStelleBis();
String s21 = f2.getSStelleVon();
String s23 = f2.getSStelleBis();

//--> erstmal nach wert1 (asc) sortieren
int result = s11.compareTo(s21);
switch (result) {
//--> bei Gleichheit weitere Sortierung
//--> nach wert3 (desc)
case 0: return 0 | s23.compareTo(s13);
default: return result;
}
}
};
}
}

Die Klasse Filter:

public class Filter{

private String sFilterNr;
private String sStelleVon;
private String sStelleBis;
private String sWbVon;
private String sWbBis;
private String sProz;

public Filter(){
}

public Filter(
String sFilterNr, String sStelleVon,
String sStelleBis, String sWbVon,
String sWbBis, String sProz){

this.sFilterNr = sFilterNr;
this.sStelleVon = sStelleVon;
this.sStelleBis = sStelleBis;
this.sWbVon = sWbVon;
this.sWbBis = sWbBis;
this.sProz = sProz;
}

public String getSFilterNr() {
return sFilterNr;
}
public String getSStelleBis() {
return sStelleBis;
}
public String getSStelleVon() {
return sStelleVon;
}
public String getSWbBis() {
return sWbBis;
}
public String getSWbVon() {
return sWbVon;
}
public String getSProz() {
return sProz;
}
}

In der Main:

Vergleichen vgl = new Vergleichen();
Collections.sort(list, vgl);

ODER:
Collections.sort(list, Vergleichen.getComparator());

Aber nix geht wieder. Es wird folgende Fehlermeldung angezeigt:
The method sort in the type collections is not applicable for the
arguments (ArrayList, Vergleichen)

Könntest du mir bitte nochmal zeigen, wie das mit einer eigenen Klasse
funktioniert?
Vielen Dank
cu
Heidi
Sascha Broich
2006-03-07 15:46:56 UTC
Permalink
Post by HeidiWeber
Hallo Alfred,
Vielen Dank für deine extreme Geduld.
Da du eine eigene Comparator-Klasse erstellen würdest, habe ich das
public class Vergleichen {
Deine Klasse muss auch das Interface Comparator implementieren.
D.h. sie muss folgendes Gerüst haben:

public class Vergleichen implements Comparator
{
public int compare(Object o1, Object o2)
{
...
}
}

Ab Java 1.5 geht auch

public class Vergleichen implements Comparator<Filter>
{
public int compare(Filter f1, Filter f2)
{
...
}
}

Du solltest dich unbedingt über Interfaces, Klassen und deren Beziehungen
miteinander informieren.


Sascha Broich
--
Weil, so schließt er messerscharf,
nicht sein kann, was nicht sein darf.
(Die unmögliche Tatsache, C. Morgenstern)
HeidiWeber
2006-03-07 16:39:54 UTC
Permalink
Nochmals vielen Dank euch allen. So wies aussieht gehts endlich:))
Werde mich morgen nochmal melden obs auch wirklich geht. Für heute
langts...

Noch einen schönen Abend
cu
Heidi
Alfred
2006-03-07 19:04:09 UTC
Permalink
Post by HeidiWeber
Hallo Alfred,
Vielen Dank für deine extreme Geduld.
Da du eine eigene Comparator-Klasse erstellen würdest, habe ich das
....
Für Comparable musst du compareTo(...) implementieren
und für Comparator compare(...). Java sucht beim Aufruf
Collections.sort(...) nach einer Klasse, die Comparator
entweder selbst implementiert -> das führt zu Collections.sort(list)
oder eben nach einem übergebenen Comparator, also muss deine
Klasse Vergleichen das Interface Comparator implementieren.
Zum Bleistift so:

public class FilterComparator implements Comparator {
^^^^^^^^^^^^^^^^^^^^^
public int compare(Object o1, Object o2) {
Filter f1 = (Filter)o1;
Filter f2 = (Filter)o2;
String s11 = f1.getStelleVon();
String s12 = f1.getWbVon();
String s21 = f2.getStelleVon();
String s22 = f2.getWbVon();
int result = s11.compareTo(s21);
switch (result) {
case 0: return 0 | s22.compareTo(s12);
default: return result;
}
}
}

//--> verzichte auf das 's' vor dem Variablennamen, das
//--> ist ungarische Notation, die in der OO-Welt ausgedient
//--> hat, ein Variablenname soll ausdrücken, _was_ die
//--> Variable speichert und nicht von welchem Typ sie ist
//--> das sieht man (frau) auch so
public class Filter {
private String filterNr, proz;
private String stelleVon, stelleBis;
private String wbVon, wbBis;

public Filter(
String filterNr, String stelleVon, String stelleBis,
String wbVon, String wbBis, String proz)
{
this.filterNr = filterNr;
this.stelleVon = stelleVon;
this.stelleBis = stelleBis;
this.wbVon = wbVon;
this.wbBis = wbBis;
this.proz = proz;
}

public String getFilterNr() { return filterNr; }
public String getStelleVon() { return stelleVon; }
public String getStelleBis() { return stelleBis; }
public String getWbVon() { return wbVon; }
public String getWbBis() { return wbBis; }
public String getProz() { return proz; }

public String toString () {
StringBuffer buf = new StringBuffer();
buf.append(filterNr).append(';');
buf.append(stelleVon).append(';').append(stelleBis).append(';');
buf.append(wbVon).append(';').append(wbBis).append(';');
buf.append(proz);
return buf.toString();
}
}

Und nun benutzen:

public static void main (String[] args) {
List data = new ArrayList();
fillFilterList(data);
System.out.println("-------- Unsortiert ------------------");
printFilterList(data);
Collections.sort(data, new FilterComparator()); //--> !!!
System.out.println("-------- Sortiert ------------------");
printFilterList(data);
}

private static void printFilterList (List list) {
Filter record = null;
for (Iterator iter = list.iterator(); iter.hasNext(); ) {
record = (Filter)iter.next();
//--> ruft implizit record.toString() auf
System.out.println(record);
}
}
private static void fillFilterList (List list) {
list.add(new Filter("1", "4", "o", "a", "a", "5"));
list.add(new Filter("2", "4", "o", "9", "b", "10"));
list.add(new Filter("3", "abc", "o", "ABC", "c", "15"));
list.add(new Filter("4", "abc", "o", "DEF", "d", "20"));
list.add(new Filter("5", "abc", "o", "GHI", "e", "5"));
list.add(new Filter("6", "4", "6", "d", "f", "10"));
list.add(new Filter("7", "9", "x", "4", "g", "15"));
list.add(new Filter("8", "7", "s", "2", "h", "20"));
...
}

Alfred
Ps: aber du solltest wirklich mal was über OOP lesen, z.B. hier:
http://de.wikipedia.org/wiki/Objektorientierung
http://www.galileocomputing.de/openbook/javainsel3/javainsel_030000.htm#Rxxjavainsel_030000256KlassenundObjekte
Zum Download: http://www.javabuch.de/
HeidiWeber
2006-03-08 16:30:05 UTC
Permalink
Hallo Alfred,

bedanke mich nochmals recht herzlich. Leider hatte ich bis jetzt noch
nichts mit OOP zu tun. Komme aus der C bzw. Cobol Welt. Und da gehts
irgendwie anders. Ich habe auch schon versucht anhand verschiedenen
Büchern und Tutorials Java zu lernen - ist aber ein extrem mühsamer
Weg:((

Noch einen schönen Abend - und vielleicht bis zum nächsten Problem:)
cu
Heidi

HeidiWeber
2006-02-28 17:12:42 UTC
Permalink
Hallo,

vielen Dank euch allen v.a. an Alfred. Deine Ausführungen/Beispiel
haben wirklich extrem geholfen. Ich glaube ich muss mich noch stark in
Comparable (und in in Java) einarbeiten. Die "print"-Methode ist auch
nicht schlecht gelöst:)

Noch einen schönen Fasching...
cu
Heidi
Loading...