Domanda

Ho un elenco di oggetti che devo ordinare in base alle proprietà di uno dei loro campi. Ho sentito che SortedMap e Comparators sono il modo migliore per farlo.

  1. Implemento Comparable con la classe che sto ordinando o creo una nuova classe?
  2. Come posso creare un'istanza di SortedMap e passare al comparatore?
  3. Come funziona l'ordinamento? Ordinerà automaticamente tutto quando vengono inseriti nuovi oggetti?

Modifica Questo codice mi sta dando un errore:

private TreeMap<Ktr> collection = new TreeMap<Ktr>();

(Ktr implementa Comparator<Ktr>). Eclipse dice che si aspetta qualcosa come TreeMap<K, V>, quindi il numero di parametri che sto fornendo non è corretto.

È stato utile?

Soluzione

  1. Il modo più semplice è implementare Comparable con i tuoi oggetti esistenti, anche se potresti invece creare un Comparator e passarlo a SortedMap.
    Tieni presente che this e new TreeMap<MyObject>() sono due cose diverse; una classe che implementa Maps confronta TreeMap con un altro oggetto, mentre una classe che implementa Collections.sort confronta due altri .
  2. Se si implementa Comparator<MyObject>, non è necessario passare nulla di speciale nel costruttore. Chiama Collections.sort(List, Comparator). ( Modifica: tranne che ovviamente <=> hanno bisogno di due parametri generici, non uno. Silly me!)
    Se invece crei un'altra classe che implementa <=>, passa un'istanza di quella classe al costruttore.
  3. Sì, secondo <=> Javadocs .

Modifica: rileggendo la domanda, nulla di tutto ciò ha senso. Se hai già un elenco, la cosa ragionevole da fare è implementare <=> e quindi chiamare <=> su di esso. Non sono necessarie mappe.

Un piccolo codice:

public class MyObject implements Comparable<MyObject> {
    // ... your existing code here ...
    @Override
    public int compareTo(MyObject other) {
        // do smart things here
    }
}

// Elsewhere:
List<MyObject> list = ...;
Collections.sort(list);

Come con <=>, è possibile invece creare un <=> e passarlo a <=> .

Altri suggerimenti

1.

Dipende dalla situazione. Diciamo che l'oggetto A dovrebbe ordinare prima dell'oggetto B nel tuo set. Se in genere ha senso considerare A meno di B, implementare Comparable avrebbe senso. Se l'ordine ha senso solo nel contesto in cui si utilizza il set, probabilmente è necessario creare un comparatore.

2.

new TreeMap(new MyComparator());

O senza creare una classe MyComparator:

new TreeMap(new Comparator<MyClass>() {
    int compare(MyClass o1, MyClass o2) { ... }
});

3. Sì.

Dato che hai un elenco e ricevi un errore perché hai un argomento sulla mappa, suppongo che tu voglia un set ordinato:

SortedSet<Ktr> set = new TreeSet<Ktr>(comparator);

Ciò manterrà il set ordinato, ovvero un iteratore restituirà gli elementi nel loro ordinamento. Esistono anche metodi specifici per SortedSet quali potresti voler usare. Se vuoi anche tornare indietro puoi usare NavigableSet .

La mia risposta presuppone che tu stia utilizzando TreeMap l'implementazione di SortedMap.

1.) Se si utilizza Comparable, è possibile scegliere. Puoi implementare Comparator direttamente sulla tua classe o passare un <=> separato al costruttore.

2.) Esempio:

Comparator<A> cmp = new MyComparator();
Map<A,B> map = new TreeMap<A,B>(myComparator);

3.) Sì, è corretto. Internamente TreeMap utilizza un albero rosso-nero memorizzare gli elementi nell'ordine in cui sono inseriti; il costo del tempo per eseguire un inserimento (o recupero) è O (log N).

Fai un Comparator<ClassYouWantToSort>. Quindi il comparatore confronta il campo su cui desideri ordinare.

Quando si crea TreeMap, si crea un TreeMap<ClassYouWantToSort> e si passa in Comparator come argomento. Quindi, quando si inseriscono oggetti di tipo ClassYouWantToSort, Comparable utilizza il Comparables per ordinarli correttamente.

EDIT: come osserva Adamski, puoi anche creare Map stesso TreeSet. Il vantaggio è che hai meno classi da gestire, il codice è più semplice e <=> ottiene un comodo ordinamento predefinito. Lo svantaggio è che <=> potrebbe non avere un singolo ordinamento ovvio, quindi dovrai comunque implementare <=> per altre situazioni. Inoltre, potresti non essere in grado di modificare <=>.

EDIT2: se hai solo un mucchio di oggetti che stai lanciando nella raccolta e non è un <=> (cioè non è una mappatura da un insieme di oggetti a un altro), allora vuoi un <=> , non un <=>.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top