Permalänk

Java, Arraylist sort

Håller på att göra en highscore lista till ett spel (Guessing game) jag gjort i Java.
I highscore listan behöver jag ha namn,poäng och tid. Den ska sortera highscoren efter poäng och om man har samma poäng så sorterar den efter tid.

Så här långt har jag kommit på highscoren:

ArrayList<String> highScore = new ArrayList<String>(); */SPEL KOD */ Collections.sort(highScore); for(int i=0; i<highScore.size(); i++){ System.out.println(highScore.get(i));}

Någon som har en idé på hur jag kan göra detta?

Permalänk
Medlem
Permalänk

Du får göra en egen Comparator(http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Compar...) och använda den som andra argument i sort metoden för att sortera highscoren.

Permalänk
Medlem

Gör en ny klass för highscore, låt den klassen hålla namn, poäng och tid. Sedan skapar du en lista över samtliga highscores (ArrayList<HighScore> istället för <String>). Highscore bör sedan implementera Comparable<HighScore>.

Permalänk
Skrivet av erifri:

Gör en ny klass för highscore, låt den klassen hålla namn, poäng och tid. Sedan skapar du en lista över samtliga highscores (ArrayList<HighScore> istället för <String>). Highscore bör sedan implementera Comparable<HighScore>.

Tyvärr så får vi endast ha en klass och endast en public method, detta är vår första uppgift ^^

Permalänk
Medlem
Skrivet av Mostwanted:

Tyvärr så får vi endast ha en klass och endast en public method, detta är vår första uppgift ^^

Du kan komma runt det genom att baka in namn, tid och score i din highscore sträng och sedan göra en egen comparator som splittar strängen igen och tar ut varje del för sig och gör jämförelser. Drog ihop ett halvfärdigt exempel:

final String delimiter = "|"; ArrayList<String> highScore = new ArrayList<String>(); highScore.add("Gnejs | 282222 | 2012-09-27"); highScore.add("Mostwanted | 94 | 2012-09-28"); highScore.add("A-First | 282222 | 2012-09-29"); Comparator comparator = new Comparator<String>() { @Override public int compare(String o1, String o2) { StringTokenizer tokenizer = new StringTokenizer(o1, delimiter); String name = tokenizer.nextToken(); Integer score = Integer.parseInt(tokenizer.nextToken().trim());//Bryt ut detta till en private method så det blir snyggare String time = tokenizer.nextToken();//String -> date, jag e lat just nu-.- StringTokenizer tokenizer2 = new StringTokenizer(o2, delimiter); String name2 = tokenizer2.nextToken(); Integer score2 = Integer.parseInt(tokenizer2.nextToken().trim()); String time2 = tokenizer2.nextToken(); if(score2.compareTo(score) == 0){//jämför score, om lika, jämför något annat if(name.compareTo(name2) == 0){ //TODO date/time ? }else{ return name.compareTo(name2); } }else{ return score2.compareTo(score); } return 0; } }; Collections.sort(highScore, comparator); for(String hs : highScore){ System.out.println(hs); }

Utskriften blir då
A-First | 282222 | 2012-09-29
Gnejs | 282222 | 2012-09-27
Mostwanted | 94 | 2012-09-28

Så A-First kom före pga namnet fast de hade samma poäng.

Edit: Såg att du hade tid å inte datum och att man skulle sortera efter tid om poängen va lika, men det kan du nog klura ut hur man gör med exemplet hur som

Visa signatur

Spelrigg: 800D| i7 3930K@4,7 GHz - Custom WC | 32 GB Kingston HyperX Beast | 7970 GHz X-Edition |1x30 Dell U3011, 2x27" | Sennheiser HD650 | Xonar Essence STX |
Laptop: G74SX 17,3" 120 Hz 3D |
Server: Phenom II X4 955BE | Corsair XMS3 8 GB | 16 HDDs, 27 TB |
HTPCs: ASUS EEE Box 1.8 Ghz | Blu-Ray | OCZ Vertex 2 60 GB | 4 GB RAM |

Permalänk

Detta fungerar om du "sparar" tid i millisekunder och sedan konverterar det till minuter/sekunder för visning av highscore sedan.

public static void main(String[] args) { ArrayList<String> highscore = new ArrayList<String>(); highscore.add("kalle 445 1231237"); highscore.add("anka 333 123123"); highscore.add("musse 445 1231233"); highscore.add("pigg 333 123113"); Collections.sort(highscore, new Comparator() { public int compare(Object o1, Object o2) { String[] h1 = ((String) o1).split(" "); String[] h2 = ((String) o2).split(" "); int score1 = Integer.parseInt(h1[1]); int score2 = Integer.parseInt(h2[1]); if (score1 == score2) { long time1 = Long.parseLong(h1[2]); long time2 = Long.parseLong(h2[2]); if (time1 == time2) { return 0; } else if (time1 < time2) { return -1; } else { return 1; } } else if (score1 > score2) { return -1; } else { return 1; } } }); for (String str : highscore) { System.out.println(str); } }

Resultatet av koden blir

musse 445 1231233 kalle 445 1231237 pigg 333 123113 anka 333 123123

Musse och Kalle har lika många poäng men kalle tog mer tid på sig.

Permalänk
Skrivet av Formel117:

Detta fungerar om du "sparar" tid i millisekunder och sedan konverterar det till minuter/sekunder för visning av highscore sedan.

public static void main(String[] args) { ArrayList<String> highscore = new ArrayList<String>(); highscore.add("kalle 445 1231237"); highscore.add("anka 333 123123"); highscore.add("musse 445 1231233"); highscore.add("pigg 333 123113"); Collections.sort(highscore, new Comparator() { public int compare(Object o1, Object o2) { String[] h1 = ((String) o1).split(" "); String[] h2 = ((String) o2).split(" "); int score1 = Integer.parseInt(h1[1]); int score2 = Integer.parseInt(h2[1]); if (score1 == score2) { long time1 = Long.parseLong(h1[2]); long time2 = Long.parseLong(h2[2]); if (time1 == time2) { return 0; } else if (time1 < time2) { return -1; } else { return 1; } } else if (score1 > score2) { return -1; } else { return 1; } } }); for (String str : highscore) { System.out.println(str); } }

Resultatet av koden blir

musse 445 1231233 kalle 445 1231237 pigg 333 123113 anka 333 123123

Musse och Kalle har lika många poäng men kalle tog mer tid på sig.

Tack allesammans, vi ska försöka göra en lösning, vi återkommer om det blir problem igen
skriver ut sedan all kod vi har gjort.

Permalänk
Skrivet av Formel117:

Detta fungerar om du "sparar" tid i millisekunder och sedan konverterar det till minuter/sekunder för visning av highscore sedan.

public static void main(String[] args) { ArrayList<String> highscore = new ArrayList<String>(); highscore.add("kalle 445 1231237"); highscore.add("anka 333 123123"); highscore.add("musse 445 1231233"); highscore.add("pigg 333 123113"); Collections.sort(highscore, new Comparator() { public int compare(Object o1, Object o2) { String[] h1 = ((String) o1).split(" "); String[] h2 = ((String) o2).split(" "); int score1 = Integer.parseInt(h1[1]); int score2 = Integer.parseInt(h2[1]); if (score1 == score2) { long time1 = Long.parseLong(h1[2]); long time2 = Long.parseLong(h2[2]); if (time1 == time2) { return 0; } else if (time1 < time2) { return -1; } else { return 1; } } else if (score1 > score2) { return -1; } else { return 1; } } }); for (String str : highscore) { System.out.println(str); } }

Resultatet av koden blir

musse 445 1231233 kalle 445 1231237 pigg 333 123113 anka 333 123123

Musse och Kalle har lika många poäng men kalle tog mer tid på sig.

ArrayList<String> highScore = new ArrayList<String>(); highScore.add(scan.next() + tries + time); Collections.sort(highScore, new Comparator(){ private int Compare(Object tries, Object time){ String[] h1 = ((String) tries).split(" "); String[] h2 = ((String) time).split(" "); int score1 = Integer.parseInt(h1[1]); int score2 = Integer.parseInt(h2[1]); if(score1 == score2) { long time1 = Long.parseLong(h1[2]); long time2 = Long.parseLong(h2[2]); if (time1 == time2){ return 0; }else if (time1 < time2){ return -1; }else { return 1;} }else if (score1 > score2) { return 1; }else{ return 1; } } }); for (String str : highScore){ System.out.println(str);}

Vi får:

javac game3.java
game3.java:99: error: <anonymous start$1> is not abstract and does not override
abstract method compare(Object,Object) in Comparator
Collections.sort(highScore, new Comparator(){
^
Note: game3.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error

Permalänk
Medlem

private int Compare(Object tries, Object time){ är fel
litet C ska det va samt den får inte vara private

Visa signatur

Spelrigg: 800D| i7 3930K@4,7 GHz - Custom WC | 32 GB Kingston HyperX Beast | 7970 GHz X-Edition |1x30 Dell U3011, 2x27" | Sennheiser HD650 | Xonar Essence STX |
Laptop: G74SX 17,3" 120 Hz 3D |
Server: Phenom II X4 955BE | Corsair XMS3 8 GB | 16 HDDs, 27 TB |
HTPCs: ASUS EEE Box 1.8 Ghz | Blu-Ray | OCZ Vertex 2 60 GB | 4 GB RAM |

Permalänk
Skrivet av Gnejs:

private int Compare(Object tries, Object time){ är fel
litet C ska det va samt den får inte vara private

Tack för hjälpen, men får detta felmeddelande: nu när vi har ändrat: Note game3.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

Vågar inte använda -Xlint då jag inte vet vad det är ^^

highScore.add(scan.next() + tries + time); Collections.sort(highScore, new Comparator(){ public int compare(Object tries, Object time){ String[] h1 = ((String) tries).split(" "); String[] h2 = ((String) time).split(" "); int score1 = Integer.parseInt(h1[1]); int score2 = Integer.parseInt(h2[1]); if(score1 == score2) { long time1 = Long.parseLong(h1[2]); long time2 = Long.parseLong(h2[2]); if (time1 == time2){ return 0; }else if (time1 < time2){ return -1; }else { return 1;} }else if (score1 > score2) { return -1; }else{ return 1; } } }); for (String str : highScore){ System.out.println(str);}

Permalänk
Medlem

Det är antagligen bara varning för att ni inte har angett typ för comparatorn, om ni kollar mitt exempel istället så ser ni hur det bör se ut-.-

Visa signatur

Spelrigg: 800D| i7 3930K@4,7 GHz - Custom WC | 32 GB Kingston HyperX Beast | 7970 GHz X-Edition |1x30 Dell U3011, 2x27" | Sennheiser HD650 | Xonar Essence STX |
Laptop: G74SX 17,3" 120 Hz 3D |
Server: Phenom II X4 955BE | Corsair XMS3 8 GB | 16 HDDs, 27 TB |
HTPCs: ASUS EEE Box 1.8 Ghz | Blu-Ray | OCZ Vertex 2 60 GB | 4 GB RAM |

Permalänk
Skrivet av Gnejs:

Det är antagligen bara varning för att ni inte har angett typ för comparatorn, om ni kollar mitt exempel istället så ser ni hur det bör se ut-.-

Så här långt har jag kommit men den sorterar fortfarande lite fel.

private static void sort(ArrayList<String> name, ArrayList<Integer> score, ArrayList<Double> time) { String temp; for (int i = score.size() - 1; i >= 1; i--) { int max = score.get(o); double min_t = time.get(o); int index = 0; int index_t = 0; for (int j = 1; j <= i; j++) { if (max < score.get(j)) { max = score.get(j); index = j; if(max == score.get(ij) { if(min_t > time.get(j)) { min_t = time.get(ij; index_t = j; } } } } if (index != i) { score.set(index, score.get(i)); score.set(i, max); temp = name.get(i); name.set(index, name.get(index_t)); name.set(i, temp); time.set(index, min_t); time.set(i, time.get(i)); } } }

Den första blev fel
Resultat:

***Welcome to the guessing game*** Number to guess is: 426 *** Start guessing, it's a number between 1-1000 *** Guess number:400 Too low, go higher Guess number:426 *** Correct! *** *** You gussed the correct number in 2 guesses and 1.095 seconds Enter your name: Pontus Do you wan't to play again? (y/n) y Names|Score Pontus || 2 || 1.095 Number to guess is: 392 *** Start guessing, it's a number between 1-1000 *** Guess number:390 Too low, go higher Guess number:392 *** Correct! *** *** You gussed the correct number in 2 guesses and 12.454 seconds Enter your name: Hosseini Do you wan't to play again? (y/n) n *** The game is over *** Names|Score Hosseini || 2 || 12.454 Pontus || 2 || 1.095

Den andra blev rätt...

***Welcome to the guessing game*** Number to guess is: 305 *** Start guessing, it's a number between 1-1000 *** Guess number:300 Too low, go higher Guess number:305 *** Correct! *** *** You gussed the correct number in 2 guesses and 2.525 seconds Enter your name: Pontus Do you wan't to play again? (y/n) y Names|Score Pontus || 2 || 2.525 Number to guess is: 436 *** Start guessing, it's a number between 1-1000 *** Guess number:430 Too low, go higher Guess number:436 *** Correct! *** *** You gussed the correct number in 2 guesses and 1.242 seconds Enter your name: Test Do you wan't to play again? (y/n) n *** The game is over *** Names|Score Test || 2 || 1.242 Pontus || 2 || 2.525

Permalänk
Medlem

1) Din kod går inte att kompilera då den innehåller syntaxfel; saknas parenteser, använder variabler som inte finns ( ij ? ) samt kör get() med o istället för 0.
2) Koden är smått oläslig så orkar inte sätta mig in i den eller varför den inte funkar.
3) Du loopar baklänges och framlänges vilket spontant känns väldigt skumt, även din inre loopar börjar på 1 istället för 0 vilket inte lär funkar så bra då listans index börjar på 0.

Sen ett tips då metoden kan köras för sig, skapa upp en samling med highscore-data som ni kan testa med utan att behöva "spela" -.-

Visa signatur

Spelrigg: 800D| i7 3930K@4,7 GHz - Custom WC | 32 GB Kingston HyperX Beast | 7970 GHz X-Edition |1x30 Dell U3011, 2x27" | Sennheiser HD650 | Xonar Essence STX |
Laptop: G74SX 17,3" 120 Hz 3D |
Server: Phenom II X4 955BE | Corsair XMS3 8 GB | 16 HDDs, 27 TB |
HTPCs: ASUS EEE Box 1.8 Ghz | Blu-Ray | OCZ Vertex 2 60 GB | 4 GB RAM |