# String-Array nach Datum sortieren



## SteeL1942 (24. Jan 2010)

Ich habe ein String-Array. In dem Array sind also mehrere Strings. Jeder String beginnt mit einem Datum und einer Uhrzeit. Danach kommt ein wenig text, also so ungefähr:

24.01.2010 16:40:50 text text text
23.01.2010 13:45:17 lol lol lol
24.01.2010 11:38:56 xd xD xd

jetzt möchte ich, dass das array halt nach datum bzw uhrzeit sortiert wird, sodass es dann so aussieht:

23.01.2010 13:45:17 lol lol lol
24.01.2010 11:38:56 xd xD xd
24.01.2010 16:40:50 text text text

ich hatte schonmal einen versuch gestartet, es mit Arrays.sort zu lösen. hat natürlich nicht geklappt 


```
private void Sortiere()
	{
		Arrays.sort(Daten);
		Ergebnis.setText("");
		int i = 0;
		do
		{
			Ergebnis.append(Daten[i]+"\n");
			i=i+1;
		}while(i<=DatenNum);
	}
```

Das String-Array heißt Daten; DatenNum ist ein int-wert, der angibt, wie viel String-werte im array sind. anschließend sollen die Strings in der textarea Ergebnis angezeigt werden...

habe auch schon mal gegoogelt bzw hier im FAQ geschaut, aber das hat mir auch nicht weiter geholfen...

hoffe, dass ihr mir da weiter helfen könnt


----------



## eRaaaa (24. Jan 2010)

Wenn das Datum + Zeit immer dd.mm.yyyy HH:mm:ss aufgebaut ist, könnte man das vllt irgendwie so lösen:

```
final SimpleDateFormat df = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
	Arrays.sort(Daten, new Comparator<String>() {
	    @Override
	    public int compare(String o1, String o2) {
		Date d1 = null, d2 = null;
		try {
		    d1 = df.parse(o1.substring(0, 19));
		    d2 = df.parse(o2.substring(0, 19));
		} catch (ParseException e) {
		    e.printStackTrace();
		}
		return d1.compareTo(d2);
	    }
	});
```

(oder man speichert Datum und Text halt getrennt)

/edit: bzw ist ja quatsch (oh man )...Arrays.sort(Daten) sollte doch ausreichen???! (ich bin verwirrt !  )

/edit2: Ist das Problem nicht vllt eher [c]Ergebnis.append(Daten[DatenNum]+"\n");[/c] ? Du greifst ja immer auf den gleichen Index zu ? (wobei ich mich frage, wenn DatenNum = Länge des Arrays ist, wieso dann keine Exception fliegt?! ???:L )


----------



## SteeL1942 (24. Jan 2010)

Upps! ich hab mich vertan ich korrigiere mal die methode.  das i gehört ja in die [] rein xD

also ich bin mir ziemlich sicher, dass es mit Arrays.sort(Daten) nicht geht, weil er mir nämlich genau in der zeile immer einen fehler ausgibt:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.sort(Unknown Source)
	at Rechner.Sortiere(Rechner.java:196)
	at Rechner.access$0(Rechner.java:194)
	at Rechner$1.actionPerformed(Rechner.java:75)
	at java.awt.Button.processActionEvent(Unknown Source)
	at java.awt.Button.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)

ka, ob dir das mehr sagt....

EDIT: hab es jetzt mal so probiert, wie du vorgeschlagen hattest, dabei kam dann diese Fehlermeldung in der konsole:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at Rechner$3.compare(Rechner.java:202)
	at Rechner$3.compare(Rechner.java:1)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.sort(Unknown Source)
	at Rechner.Sortiere(Rechner.java:197)
	at Rechner.access$0(Rechner.java:195)
	at Rechner$1.actionPerformed(Rechner.java:76)
	at java.awt.Button.processActionEvent(Unknown Source)
	at java.awt.Button.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)

da irritiert mich nur, dass er was an zeile 1 zu meckern hat, denn da steht einfach

```
import java.awt.*;
```

und der eigendlich fehler ist ja in zeile 202, also der hier:

```
d1 = df.parse(o1.substring(0, 19));
```


----------



## eRaaaa (24. Jan 2010)

Wie kommen die Strings in das Array? Sieht wohl danach aus, als wenn da der Fehler liegt, denn folgendes läuft:

```
String s1 = "24.01.2010 16:40:50 text text text";
	String s3 = "23.01.2010 13:45:17 lol lol lol";
	String s2 = "24.01.2010 11:38:56 xd xD xd";
	String[] array = { s1, s2, s3 };
	Arrays.sort(array);
	for (String string : array) {
	    System.out.println(string);
	}
```


----------



## SteeL1942 (24. Jan 2010)

also die Strings werden mit dieser Methode ins Array geschrieben:


```
private void Schreibe(int ax, int ay, int zx, int zy)
	{
		Daten[DatenNum] = (df.format(Abstag)+"   [village]"+ax+"|"+ay+"[/village]  ->  [village]"+zx+"|"+zy+"[/village]");
		DatenNum = DatenNum+1;
	}
```

Wenn das programm startet, ist der Int DatenNum 0. und jedes mal, wenn er wieder einen eintrag rein schreibt, wir der wert einen hoch gesetzt, damit er halt beim nächsten mal nicht überschreibt. 
und wie gesagt: die strings haben immer dieses muster: dieses Datum, was über DateFormat so formatiert wurde und dann halt immer [village]xxx|yyy[/village] ->[village[xxx|yyy[/village] dahinter. das programm läuft erstmal durch. anschließend wird die sortiermethode über einen button ausgelöst.


----------



## LoR (24. Jan 2010)

Unter der Bedingung, dass das Datums-/Zeitformat immer das selbe ist könntest du die ganze Sache so lösen:


```
import java.util.Arrays;
import java.util.Comparator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {

    private static final Matcher date_matcher = Pattern.compile("(\\d{2})\\.(\\d{2})\\.(\\d{4})\\s(\\d{2}):(\\d{2}):(\\d{2})").matcher("");

    public static void main(String[] args) {
        String[] daten = {"24.01.2010 16:40:50 text text text",
            "23.01.2010 13:45:17 lol lol lol",
            "24.01.2010 11:38:56 xd xD xd"
        };

        sortiere(daten);

        for (String s : daten) {
            System.out.println(s);
        }
    }

    private static void sortiere(String[] daten) {
        Arrays.sort(daten, new Comparator<String>() {

            public int compare(String o1, String o2) {
                long h1 = hash(o1);
                long h2 = hash(o2);
                if (h1 > h2) {
                    return 1;
                } else if (h1 < h2) {
                    return -1;
                }
                return 0;
            }
        });
    }

    private static long hash(String str) {
        date_matcher.reset(str);
        if (date_matcher.find()) {
            int tt = Integer.parseInt(date_matcher.group(1));
            int mm = Integer.parseInt(date_matcher.group(2));
            int jjjj = Integer.parseInt(date_matcher.group(3));
            int HH = Integer.parseInt(date_matcher.group(4));
            int MM = Integer.parseInt(date_matcher.group(5));
            int SS = Integer.parseInt(date_matcher.group(6));
            int datum = jjjj * 10000 + mm * 100 + tt;
            int uhrzeit = HH * 10000 + MM * 100 + SS;
            return (long) datum << 32 | (long) uhrzeit;
        }
        return 0;
    }
}
```

Hau rein 

//EDIT



eRaaaa hat gesagt.:


> Wie kommen die Strings in das Array? Sieht wohl danach aus, als wenn da der Fehler liegt, denn folgendes läuft:
> 
> ```
> String s1 = "24.01.2010 16:40:50 text text text";
> ...



Das funktioniert nur in diesem Fall. Ansonsten ist Sortierung nicht richtig. Z.B. wenn folgender String enthalten wäre: "01.01.2011 11:38:56 blub blub blub".


----------



## SteeL1942 (24. Jan 2010)

Also das läuft immernoch nicht...

hier mal meine ganze klasse Sortierer:


```
import java.awt.*;
import java.awt.event.*;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.regex.*;

public class Sortierer extends Frame{

    private String Daten [] = new String [1000];
    private TextArea Ergebnis;
	private Button Ende, Sort;
	final SimpleDateFormat df = new SimpleDateFormat( "dd.MM.yyyy HH:mm:ss" );
    
	public Sortierer(String [] pDaten)
	{
		Daten = pDaten;
		
		this.setTitle("Liste");
		
		Ergebnis = new TextArea();
		Ende = new Button ("Schließen");
		Sort = new Button ("Sortiere");

		this.setLayout(null);
		
		Ergebnis.setBounds(25,30,500,500);
		Sort.setBounds(330,570,100,20);
		Ende.setBounds(440,570,100,20);
		
		add(Ergebnis);
		add(Sort);
		add(Ende);
		
		Sort.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                Sortiere();
            }});
		
		Ende.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                setVisible(false);
            }});	
	}
	
	private void Sortiere()
	{
		Arrays.sort(Daten, new Comparator<String>() {
			 
            public int compare(String o1, String o2) {
                long h1 = hash(o1);
                long h2 = hash(o2);
                if (h1 > h2) {
                    return 1;
                } else if (h1 < h2) {
                    return -1;
                }
                return 0;
            }
        });

	}
	
	private static final Matcher date_matcher = Pattern.compile("(\\d{2})\\.(\\d{2})\\.(\\d{4})\\s(\\d{2}):(\\d{2}):(\\d{2})").matcher("");
	
	private static long hash(String str) {
        date_matcher.reset(str);
        if (date_matcher.find()) {
            int tt = Integer.parseInt(date_matcher.group(1));
            int mm = Integer.parseInt(date_matcher.group(2));
            int jjjj = Integer.parseInt(date_matcher.group(3));
            int HH = Integer.parseInt(date_matcher.group(4));
            int MM = Integer.parseInt(date_matcher.group(5));
            int SS = Integer.parseInt(date_matcher.group(6));
            int datum = jjjj * 10000 + mm * 100 + tt;
            int uhrzeit = HH * 10000 + MM * 100 + SS;
            return (long) datum << 32 | (long) uhrzeit;
        }
        return 0;
    }
}
```

Fehlermeldung ist diese:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at java.util.regex.Matcher.getTextLength(Unknown Source)
	at java.util.regex.Matcher.reset(Unknown Source)
	at java.util.regex.Matcher.reset(Unknown Source)
	at Sortierer.hash(Sortierer.java:67)
	at Sortierer.access$1(Sortierer.java:66)
	at Sortierer$3.compare(Sortierer.java:51)
	at Sortierer$3.compare(Sortierer.java:1)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.mergeSort(Unknown Source)
	at java.util.Arrays.sort(Unknown Source)
	at Sortierer.Sortiere(Sortierer.java:48)
	at Sortierer.access$0(Sortierer.java:46)
	at Sortierer$1.actionPerformed(Sortierer.java:37)
	at java.awt.Button.processActionEvent(Unknown Source)
	at java.awt.Button.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)


//EDIT: Ich hab die sache mit in die TextArea schreiben, erstmal wieder raus genommen. wenn nicht mal das sortieren läuft, gibts ja auch noch nichts zu schreiben


----------



## LoR (24. Jan 2010)

Habs getestet. Funktioniert einwandfrei.

Aufruf mit:

```
public static void main(String[] args) {
        String[] daten = {"24.01.2010 16:40:50 text text text",
            "23.01.2010 13:45:17 lol lol lol",
            "24.01.2010 11:38:56 xd xD xd",
            "01.01.2011 11:38:56 xd xD xd"
        };

        Sortierer s = new Sortierer(daten);
        s.setVisible(true);
    }
```

Das noch abändern (im Sortierer):

```
Sort.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                Sortiere();
                for (String s : Daten) {
                    Ergebnis.append(s);
                    Ergebnis.append("\n");
                }
            }
        });
```


----------



## Ebenius (25. Jan 2010)

Naja, nicht wenn [c]null[/c] im Array steht. ;-)

BTW: Klassennamen [c]*C*amelCase[/c], Variablen und Methoden aber [c]*c*amelCase[/c].

Ebenius


----------



## SteeL1942 (25. Jan 2010)

ahh. fehler gefunden. das array was von meinem programm an den sortierer übergeben wird, hat standardmäßig immer platz für 1000 Strings also so:


```
private String Daten [] = new String [1000];
```

es kommt aber durchaus vor, dass nicht alle plätze belegt werden und dann scheint es nicht zu klappen. ich hab jez noch ne kleine rechnung eingebaut, damit immer die passende anzahl an "plätzen" eingebaut wird - jez läufts^^

Besten Dank!


----------



## Semox (26. Jan 2010)

Hallo SteeL1942

In dem Fall um NullPointerExeptions zu vermeiden, wäre es wahrschieinlich einfacher, wenn Du linked Lists verwendest...
Durch die Verwendung doppelt verketteter Listenelemente, kannst Du Objekte dynamisch hinzufügen und löschen. Dazu braucht man zwei Listen. Die eine speichert das vorhergehende Element und die andere das folgende. Dadurch hat man die Grundlage um die Elemente immer schön beisammen im Stack zu haben. Der Garbarge Collector arbeitet schneller und es entstehen weniger Probleme in ein Datenloch zu fallen, wenn ein Element aufgerufen wird, daß gar nicht existiert. Zudem kann Deine Liste wachsen und automatisch schrumpfen...


```
DListNode<E> head;
 DListNode<E> current;

 /**
     * Eine doppelt verkettete Liste wird erzeugt mit einem
     * dummy-Knoten, der auf sich selber zeigt.
     */
    public SortedListGen() {
        DListNode<E> dummy = new DListNode<E>();
        dummy.next = dummy;
        dummy.prev = dummy;
        head = dummy;
        current = dummy;
    }

    /**
     * Hier wird geprüft, ob ein Objekt in der Liste beinhaltet ist.
     * 
     * @param o
     * @return
     */
    public boolean contain(E o) {
        boolean found = false;
        if (!empty()) {
            current = head.next;
            while ((current != head) && !found) {
                if ((current.element).compareTo(o) == 0)
                    found = true;
                else
                    current = current.next;
            }
        }
        return found;
    }

    /**
     * Ist der current-Zeiger ein gültiges Element?.
     * 
     * @return
     */
    public boolean current_in_list() {
        return (!empty() && current != head);
    }

 /**
     * Ein Element wird in die Datenmenge einsortiert.
     * 
     * @param element
     */
    public void add(E element) {
        DListNode<E> new_element = new DListNode<E>(element);
        if (empty()) {
            insert_node(head, new_element);
        } else {
            DListNode<E> temp = head;
            while ((temp.next != head)
                    && ((new_element.element).compareTo(temp.next.element) > 0)) {
                temp = temp.next;
            }
            insert_node(temp, new_element);
        } // end of if
    } // end of add
```

Es ist ein bißchen Wissen um Collections im allgemeinen nötig und wie man Interfaces programmmiert... Hoffe das inspiriert Dich ein bißchen.

Grüße,
Semo


----------

