[Java] treeSet sorteren met meerdere compareTo's

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • SMGGM
  • Registratie: Januari 2006
  • Laatst online: 11-09 17:29
Het uiteindelijke probleem ziet er wat ingewikkelder uit maar hier komt het eigenlijk op neer ;)
Ik heb een klasse (Test) dat 2 string bevat en ik wil die soteren met een treeset. Nu wil ik deze sorteren zowel op basis van de eerste string als op de tweede. De eerste is tamelijk simpel maar hoe forceer je de treeset om een andere compareTo te gaan gebruiken om zo te kunnen ordenen op de tweede string?
Java:
1
2
3
4
5
6
7
8
SortedSet<Test> testjes = Collections.synchronizedSortedSet(new TreeSet<Test>());
 
testjes.add(new Test("zzz", "aaa"));
testjes.add(new Test("bbb", "xxx"));
 
for(Test t : testjes){
    System.out.println(t.toString());
}

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Test implements Comparable {
    String one, two;
 
    public Test(String one, String two){
        this.one = one;
        this.two = two;
    }
 
    @Override
    public String toString(){
        return this.one + " " + this.two;
    }
 
    public int compareTo(Object o) {
        return this.toString().compareTo(o.toString());
    }
 
    public int compareToSecondString(Object o){
        return this.two.compareTo(o.toString());
    }
}

Het eerste zal dus logischerwijze als output dit geven:
bbb xxx
zzz aaa

Maar hoe kan ik er nu voor zorgen dat hij de compareToSecondString gaat gebruiken?

NB: het is mij opgevallen dat er een klein foutje in de tweede compareTo (als je er goed naar kijkt), maar dat doet er niet toe.

Alvast bedankt!

Acties:
  • 0 Henk 'm!

  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
De Comparator is your friend ;)

In plaats van de compareTo() op het object te overriden, implementeer 2 Comparators - een voor elke manier waarop de objecten gesorteerd moeten worden. Vervolgens kun je bij het constructen van de TreeSet als argument de Comparator meegeven die gebruikt moet worden voor het sorteren.

Acties:
  • 0 Henk 'm!

  • SMGGM
  • Registratie: Januari 2006
  • Laatst online: 11-09 17:29
Dus... Ik heb dit als Test class:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Test {
    String one, two;

    public Test(String one, String two){
        this.one = one;
        this.two = two;
    }

    @Override
    public String toString(){
        return this.one + " " + this.two;
    }

    class StringOneCompare implements Comparator<Test>{
        public int compare(Test o1, Test o2) {
            Test one = (Test) o1;
            Test two = (Test) o2;
            return one.getOne().compareTo(two.getOne());
        }
    }

    class StringTwoCompare implements Comparator<Test>{
        public int compare(Test o1, Test o2) {
            Test one = (Test) o1;
            Test two = (Test) o2;
            return one.getTwo().compareTo(two.getTwo());
        }
    }
}

Maar ik ben er niet echt uit hoe je dat als argument meegeeft in de treeset.

Wat doe ik fout?

Acties:
  • 0 Henk 'm!

  • roeleboel
  • Registratie: Maart 2006
  • Niet online

roeleboel

en zijn beestenboel

StringOneCompare en StringTwoCompare wil je niet als inner-class, maar als aparte 'normale' klasse.
Voor de treeset aan te maken doe je dan:
Java:
1
Treeset t = new TreeSet(new StringOneCompare);

Meer info: constructor van TreeSet eens bekijken.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

roeleboel schreef op zondag 18 oktober 2009 @ 14:53:
StringOneCompare en StringTwoCompare wil je niet als inner-class
Waarom wil je dat niet? Het lijkt mij prima om wat voorgedefinieerde Comparable implementaties te maken die Tests op een speciale manier vergelijken. Het zouden alleen geen nested instance classes moeten zijn, dus hij kan ze beter static maken, zodat ze niet gekoppeld zijn aan een Test instance.

[ Voor 5% gewijzigd door .oisyn op 18-10-2009 23:45 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.