Ordinamento HashMap basato su proprietà custom

DOMANDA:

Come posso ordinare un HashMap basandomi su una proprietà degli oggetti che contiene?



RISPOSTA:

E' possibile eseguire un ordinamento di un HashMap basato su una proprietà dei suoi oggetti attraverso l'utilizzo di due elementi:

Innanzitutto creiamo un bean per rappresentare gli elementi da ordinare in base ad una proprietà. Il bean sarà Tab e la proprietà position. Come avrete intuito, faremo l'ordinamento di una serie di tab come quelli che troviamo in quasi tutte le interfacce grafiche dei moderni siti web.

La nostra lista di tab (non ordinata) sarà la seguente:
  • Portfolio
  • Home
  • Contatti
  • Chi siamo
Da ordinare nel seguente modo:
  1. Home
  2. Chi siamo
  3. Portfolio
  4. Contatti
Innanzitutto creiamo il bean Tab:
public class Tab {
 
 private int position;

 public Tab(int position) {
  this.position=position;
 }

 public int getPosition() {
  return position;
 }

 public void setPosition(int position) {
  this.position = position;
 }
 
 @Override
 public String toString(){
  return "Tab in posizione "+position;
  
 }

}

Creiamo la classe PositionComparator che implementa Comparator e ci permette di definire i criteri di ordinamento (per approfondimenti vi rimando al post su Comparator):
class PositionComparator implements Comparator<String> {

 Map<String, Tab> unsortedMap;

 public PositionComparator(Map<String, Tab> unsortedMap) {
  this.unsortedMap = unsortedMap;
 }

 @Override
 public int compare(String a, String b) {
  if (unsortedMap.get(a).getPosition() < unsortedMap.get(b).getPosition()) {
   /* System.out.println(a +" e' prima di "+b);*/
   return -1;
  } else if (unsortedMap.get(a).getPosition() > unsortedMap.get(b)
    .getPosition()) {
   // System.out.println(a +" e' dopo di "+b);
   return 1;
  } else {
   return 0;
  }

 }
}

A questo punto non resta che creare la nostra applicazione Java che crea i tab in sequenza "casuale" per poi ordinarli attraverso il metodo sortTabs():
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class SortMap {

 public static void main(String[] args) {
  Map<String, Tab> tabs = new HashMap<String, Tab>();
  tabs.put("Portfolio", new Tab(3));
  tabs.put("Home", new Tab(1));
  tabs.put("Contatti", new Tab(4));
  tabs.put("Chi siamo", new Tab(2));

  System.out.println("------------Map non ordinata-----------");
  System.out.println("unsorted map: " + tabs);
  for (String key : tabs.keySet()) {
   System.out.println("tab: " + tabs.get(key).getPosition());
  }
  System.out.println("-----------------------------------\n");

  //Ordinamento
  tabs = sortTabs(tabs);

  System.out.println("------------Map ordinata-----------");
  System.out.println("sorted map: " + tabs);
  for (String key : tabs.keySet()) {
   System.out.println("tab: " + tabs.get(key).getPosition());
  }
  System.out.println("-----------------------------------");
  
 }

 public static Map<String, Tab> sortTabs(Map<String, Tab> tabs) {

  PositionComparator pc = new PositionComparator(tabs);
  TreeMap<String, Tab> sorted_map = new TreeMap<String, Tab>(pc);

  sorted_map.putAll(tabs);

  return sorted_map;
 }
}
Notiamo come la Map iniziale (riga 9) utilizzi una HashMap mentre il metodo sortTabs() una TreeMap (riga 37). La differenza fondamentale tra le due strutture dati è che TreeMap memorizza gli elementi in un albero e consente di recuperarli in un ordine di default oppure definito da chi la usa (custom, come nel nostro caso).

Ricapitoliamo brevemente il flusso logico del codice per riuscire ad ordinare una Map preesistente:
  1. Si associa la Map non ordinata al Comparator 
    • Creo il PositionComparator fornendo in input la Map dei tab
  2. Si crea una TreeMap associandole il Comparator
    • Istanzio una TreeMap fornendo in input il PositionComparator
  3. La TreeMap creata viene popolata con la Map iniziale
    • sorted_map.putAll(tabs)


L'output dell'applicazione sarà il seguente:

------------Map non ordinata-----------
unsorted map: {Chi siamo=Tab in posizione 2, Home=Tab in posizione 1, Contatti=Tab in posizione 4, Portfolio=Tab in posizione 3}
tab: 2
tab: 1
tab: 4
tab: 3
-----------------------------------

------------Map ordinata-----------
sorted map: {Home=Tab in posizione 1, Chi siamo=Tab in posizione 2, Portfolio=Tab in posizione 3, Contatti=Tab in posizione 4}
tab: 1
tab: 2
tab: 3
tab: 4
-----------------------------------

Commenti

  1. Più che un'applicazione di un ordinamento mi sembra un'applicazione di polimorfismo. Non si ordina la hashmap, si sostituisce con una treemap che è di per se ordinata, perdendo però nella ricerca. Sta di fatto che non è vero che si ordina una hashmap così

    RispondiElimina

Posta un commento

Post popolari in questo blog

Arrotondamento e troncamento in Java

Eclipse: Shortcuts (scorciatoie) da tastiera

Strutture dati: List, Set, Map

Creare un eseguibile Java