Como posso ordenar Map<String,Classe> por diversos values usando comparable ou comparator?

Pessoal,

Tenho a seguinte estrutura de dados:

private static Map<String, Entry> names;
private static Map<String, Set><Entry>> labels;
O método que insere dados na classe é o seguinte:
public static void add(final String namep, final String numberp,
final String addrp, final String descriptionp,
final GregorianCalendar dobp) {
names.put(namep, new EntryImpl(namep, numberp, addrp, descriptionp,
dobp));
}

O método que recupera dados dessa estrutura é o seguinte:

public static List<Entry> getEntries() {
return new LinkedList<Entry>(names.values());
}

E os seguintes dados inseridos nela:

static {
	names = new HashMap&lt;String, Entry&gt;();
	labels = new HashMap&lt;String, Set&gt;&lt;Entry&gt;&gt;();
	add(&quot;Elendil&quot;, &quot;12223330000&quot;, &quot;Rua dos Nerds, 0&quot;, &quot;A nerd&quot;,
			new GregorianCalendar(1980, 1, 7));
	add(&quot;Porthos&quot;, &quot;55555555555&quot;, &quot;Rua dos Nerds, 0&quot;, &quot;A nerd&quot;,
			new GregorianCalendar(1980, 1, 7));
	add(&quot;Denethor&quot;, &quot;999999999&quot;, &quot;Rua dos Nerds, 0&quot;, &quot;A nerd&quot;,
			new GregorianCalendar(1980, 1, 7));
	add(&quot;Aramis&quot;, &quot;28934792839&quot;, &quot;Rua dos Belos, 100&quot;, &quot;Someone handsome&quot;,
			new GregorianCalendar(1982, 11, 6));
	add(&quot;Athos&quot;, &quot;61616161616&quot;, &quot;Rua dos Doidos, 42&quot;, &quot;Someone mad&quot;,
			new GregorianCalendar(1990, 1, 30));
	try {
		addLabel(&quot;Elendil&quot;, &quot;work&quot;);
		addLabel(&quot;Aramis&quot;, &quot;school&quot;);
		addLabel(&quot;Aramis&quot;, &quot;work&quot;);
		removeLabel(&quot;Elendil&quot;, &quot;work&quot;);
		addLabel(&quot;Elendil&quot;, &quot;club&quot;);
	} catch (NameNotFoundException nnf) {
		nnf.printStackTrace();
	} catch (LabelNotFoundException lnf) {
		lnf.printStackTrace();
	}

}

Preciso, usando comparable ou comparator ordenar tal estrutura, especificamente names, por idade, names e addr.
Criei a seguinte classe:

public class Comparador implements Comparator<Entry> {

private static final int SORT_BY_ADDRESS = 0;
private static final int SORT_BY_AGE = 1;
private static final int SORT_BY_NAME = 2;
protected Map&lt;String, Entry&gt; entries;
public int ordem;


public void setOrdem(int ordem) {
	this.ordem = ordem;
}



public int compare(Entry o1, Entry o2) {
	
	int result = 0;
	String nome1, nome2;
	String end1, end2;
	GregorianCalendar data1, data2;
	switch (ordem) {
	case SORT_BY_ADDRESS:
		end1 = o1.getAddr();
		end2 = o2.getAddr();
		result = end1.compareToIgnoreCase(end2); // os
		break;
	case SORT_BY_AGE:
		data1 = o1.getDateOfBirth();
		data2 = o2.getDateOfBirth();
		result = data1.compareTo(data2);
		break;
	case SORT_BY_NAME:
		nome1 = o1.getName();
		nome2 = o2.getName();
		result = nome1.compareToIgnoreCase(nome2);
		break;
	}
	return result;
}

}

De dentro de meu programa principal fiz o seguinte:

int criterio; // campo pelo qual se deseja ordenar
// capturo o índice selecionado do spinner
criterio = s.getSelectedItemPosition();
Comparador comp = new Comparador();
comp.setOrdem(criterio);
e = NameDirectory.getEntries();
Collections.sort(e, comp);
String phone, addr, description, name;
GregorianCalendar data;

			for (int i = 0; i &lt; e.size(); i++) {
				name = e.get(i).getName();
				phone = e.get(i).getPhone();
				addr = e.get(i).getAddr();
				description = e.get(i).getDescription();
				data = e.get(i).getDateOfBirth();
				NameDirectory.add(name, phone, addr,description, data);
				
			}

e = NameDirectory.getEntries();

agora quando exbo o conteúdo da variável e vejo que a ordem não mudou e permanece aquela da atribuição inicial Static {… } acima.

Agradeço qualquer ajuda.

Você vai ter que começar nos ajudando:
http://www.guj.com.br/posts/list/50115.java

Pessoal,

No código abaixo crio uma estrutura de dados do tipo map a qual desejo ordenar usando comparator pelos campos Name ou DateOfBirth ou Addr.
O problema que estou encontrando é justamente porque se trata de um map. E em meu programa eu não posso alterar o tipo de dado para SortedMap nesta classe.

O método getEntries() recupera os dados.

public final class NameDirectory  {
	/**
	 * The list of names that comprises this address book.
	 */
	private static Map&lt;String, Entry&gt; names;

	/**
	 * This list of labels that we use to organize the names.
	 */
	private static Map&lt;String, Set&gt;&lt;Entry&gt;&gt; labels;
	

	/**
	 * Constructor.
	 */
	private NameDirectory() {
	}

	static {
		names = new HashMap&lt;String, Entry&gt;();
		labels = new HashMap&lt;String, Set&gt;&lt;Entry&gt;&gt;();
		add(&quot;Elendil&quot;, &quot;12223330000&quot;, &quot;Rua dos Nerds, 0&quot;, &quot;A nerd&quot;,
				new GregorianCalendar(1980, 1, 7));
		add(&quot;Porthos&quot;, &quot;55555555555&quot;, &quot;Rua dos Nerds, 0&quot;, &quot;A nerd&quot;,
				new GregorianCalendar(1980, 1, 7));
		add(&quot;Denethor&quot;, &quot;999999999&quot;, &quot;Rua dos Nerds, 0&quot;, &quot;A nerd&quot;,
				new GregorianCalendar(1980, 1, 7));
		add(&quot;Aramis&quot;, &quot;28934792839&quot;, &quot;Rua dos Belos, 100&quot;, &quot;Someone handsome&quot;,
				new GregorianCalendar(1982, 11, 6));
		add(&quot;Athos&quot;, &quot;61616161616&quot;, &quot;Rua dos Doidos, 42&quot;, &quot;Someone mad&quot;,
				new GregorianCalendar(1990, 1, 30));
		try {
			addLabel(&quot;Elendil&quot;, &quot;work&quot;);
			addLabel(&quot;Aramis&quot;, &quot;school&quot;);
			addLabel(&quot;Aramis&quot;, &quot;work&quot;);
			removeLabel(&quot;Elendil&quot;, &quot;work&quot;);
			addLabel(&quot;Elendil&quot;, &quot;club&quot;);
		} catch (NameNotFoundException nnf) {
			nnf.printStackTrace();
		} catch (LabelNotFoundException lnf) {
			lnf.printStackTrace();
		}
	}

	

	/**
	 * This method adds a new entry to the phone list.
	 * 
	 * @param namep
	 *            the name of the person who owns the phone number.
	 * @param numberp
	 *            the phone number itself.
	 * @param addrp
	 *            the address of the person.
	 * @param descriptionp
	 *            a short description about the person.
	 * @param dobp
	 *            the Date of Birth of the person.
	 */
	public static void add(final String namep, final String numberp,
			final String addrp, final String descriptionp,
			final GregorianCalendar dobp) {
		names.put(namep, new EntryImpl(namep, numberp, addrp, descriptionp,
				dobp));
	}

	
	/**
	 * Return an array with all the entries stored in this directory.
	 * 
	 * @return an array of entries.
	 */
	public static List&lt;Entry&gt; getEntries() {
		return new LinkedList&lt;Entry&gt;(names.values());
	}

	/**
	 * This method returns an entry, given a name.
	 * 
	 * @param name
	 *            the search key.
	 * @return an object of the &lt;code&gt;Entry&lt;/code&gt; type.
	 * @throws NameNotFoundException
	 *             in case the name is not in the database.
	 */
	public static Entry getEntrie(final String name)
			throws NameNotFoundException {
		if (!names.containsKey(name)) {
			throw new NameNotFoundException();
		} else {
			return names.get(name);
		}

	}

	...
}

Para fazer a ordenação, criei a seguinte classe:
Através da variável ordem, setada por fora da classe pelo método setOrdem, escolho o campo pelo qual pretendo ordenar.

public class Comparador implements Comparator&lt;Entry&gt; {

	private static final int SORT_BY_ADDRESS = 0;
	private static final int SORT_BY_AGE = 1;
	private static final int SORT_BY_NAME = 2;
	protected Map&lt;String, Entry&gt; entries;
	public int ordem;


	public void setOrdem(int ordem) {
		this.ordem = ordem;
	}

	

	public int compare(Entry o1, Entry o2) {
		
		int result = 0;
		String nome1, nome2;
		String end1, end2;
		GregorianCalendar data1, data2;
		switch (ordem) {
		case SORT_BY_ADDRESS:
			end1 = o1.getAddr();
			end2 = o2.getAddr();
			result = end1.compareToIgnoreCase(end2); // os
			break;
		case SORT_BY_AGE:
			data1 = o1.getDateOfBirth();
			data2 = o2.getDateOfBirth();
			result = data1.compareTo(data2);
			break;
		case SORT_BY_NAME:
			nome1 = o1.getName();
			nome2 = o2.getName();
			result = nome1.compareToIgnoreCase(nome2);
			break;
		}
		return result;
	}
	
	
}

Em minha classe principal fiz o seguinte, pensando em ordenar pelos referidos campos, um por vez, de acordo com escolha do usuário:

...
         List&lt;Entry&gt; e;
         int criterio; // campo pelo qual se deseja ordenar
	// capturo o índice selecionado do spinner
	criterio = s.getSelectedItemPosition();
	Comparador comp = new Comparador();
	comp.setOrdem(criterio);
	e = NameDirectory.getEntries();
	// variáveis auxiliares
	String phone, addr, description, name;
	GregorianCalendar data;
        // sortedmap para manter a ordem dos elementos
	SortedMap&lt;String,Entry&gt; sm = new TreeMap&lt;String,Entry&gt;();
	// momento da ordenação
	Collections.sort(e, comp);
        // inserção dos dados ordenados no sortedmap
        for (int i = 0; i &lt; e.size(); i++) {
		name = e.get(i).getName();
		phone = e.get(i).getPhone();
		addr = e.get(i).getAddr();
		description = e.get(i).getDescription();
		data = e.get(i).getDateOfBirth();
		sm.put(name, new EntryImpl(name, phone, addr, description,
		data));
	}
...

No entanto não sei como fazer com que minha variável names, criada na primeira classe NameDirectory, receba agora o conteúdo ordenado.

Agradeço qualquer ajuda.

O hashMap em si não pode ser ordenado. Em termos de map, o máximo que você pode ter é um TreeMap, que ordenará necessariamente pelas chaves.

Se você quer ordenar aqueles dados, terá que usar outra collection.

Alterei o tipo de dados em NameDirectory de HashMap para SortedMap x = new TreeMap(…).
Desta forma ele fica sempre ordenado pela chave. Entretanto não consigo mudar sua ordenação com o comparator.
Alguma sugestão, já tentei de tudo.

Obrigado.