Una ArrayList ordinata /2

Da Head First Java O'Reilly, capitolo 16 che tratta collezioni e programmazione generica.

L'uso del metodo statico sort() della classe Collections, che abbiamo visto nel precendente post, diventa un poco più complicato in un caso più realistico, in cui la collezione non usi un tipo standard (String, nel caso visto) ma un tipo custom.

Infatti la dichiarazione del metodo sort() é la seguente:

public static <T extends Comparable<? super T>> void sort(List<T> list)

Ne consegue che, se intendiamo usare questo metodo sulla nostra collezione, questa deve essere basata su un tipo che implementi l'interfaccia Comparable.

Creiamo quindi la classe Song che descrive le canzoni come vogliamo vengano gestite dalla nostra applicazione:

package Chap16;

public class Song implements Comparable<Song> {
private String title;
private String artist;
private int rating;

public void setArtist(String artist) {
this.artist = artist;
}

public String getArtist() {
return artist;
}

public Song(String title, String artist, int rating) {
this.title = title;
this.artist = artist;
this.rating = rating;
}

public int compareTo(Song s) {
int result = title.compareTo(s.title);
if(result == 0)
return artist.compareTo(s.artist);

return result;
}

@Override
public String toString() {
return title + " by " + artist;
}
}

L'interfaccia Comparable richiede che si implementi il medoto compareTo(), nel nostro caso si compara il titolo e, in caso che questo risulti identico, l'artista.

L'altro punto che resta scoperto é la possibilità di ordinare la collezione usando un criterio diverso da quello standard per la classe sottostante. Diciamo che nel nostro caso si voglia realizzare un ordinamento anche in base all'autore e non solo al titolo del brano.

Il metodo sort() di Collections prevede la possibilità di specificare un oggetto comparatore che definisce come comparare gli oggetti durante l'ordinamento usando questa versione di sort:

public static <T> void sort(List<T> list, Comparator<? super T> c)


Definiamo come classe interna ArtistCompare che ha proprio questo scopo:

package Chap16;

import java.util.*;

public class JukeBoxB {
private ArrayList<Song> songs = new ArrayList<Song>();

public JukeBoxB() {
getSongs();
System.out.println(songs);
Collections.sort(songs);
System.out.println(songs);
Collections.sort(songs, new ArtistCompare());
System.out.println(songs);
}

private void getSongs() {
// fake implementation
String[] fakeList = {"Pink Moon/Nick Drake/5", "Somersault/Zero 7/4",
"Shiva Moon/Prem Joshua/5", "Circles/BT (Brian Wayne Transeau)/3",
"Deep Channel/Afro Celts/3", "Passenger/Headmix/4",
"Listen/Tahiti 80/3"};
for(String s : fakeList) {
System.out.println(s);
String[] tokens = s.split("/");

int rating = Integer.parseInt(tokens[2]);
songs.add(new Song(tokens[0], tokens[1], rating));
}
}

private class ArtistCompare implements Comparator {

public int compare(Song s1, Song s2) {
return s1.getArtist().compareTo(s2.getArtist());
}
}

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

Nessun commento:

Posta un commento