Частности, порядок по алфавиту по значению

у меня есть HashMap<Object, Student> где объект является идентификатором студента, а студент является объектом от студента.

Как я могу прибегнуть к HashMap по имени студентов,student->getName()?

5 ответов


хэш-карты внутренне неупорядочены и не могут быть отсортированы.

вместо этого вы можете использовать SortedMap реализация, например TreeMap.
Однако даже отсортированная карта может сортировать только по своим ключам.

Если вы хотите отсортировать значения, вам нужно скопировать их в отсортированный список.


возможно, вы не сможете сортировать HashMap, но вы можете сделать что-то, что обеспечивает тот же эффект. Я смог отсортировать свой HashMap по убыванию значения целого числа, используя отличный код, размещенный в Javarevisited блог. Тот же принцип будет применяться к объекту HashMap :

/*
 * Java method to sort Map in Java by value e.g. HashMap or Hashtable
 * throw NullPointerException if Map contains null values
 * It also sort values even if they are duplicates
 */
public static <K extends Comparable,V extends Comparable> Map<K,V> sortByValues(Map<K,V> map){
    List<Map.Entry<K,V>> entries = new LinkedList<Map.Entry<K,V>>(map.entrySet());

    Collections.sort(entries, new Comparator<Map.Entry<K,V>>() {

        @Override
        public int compare(Entry<K, V> o1, Entry<K, V> o2) {
            return o1.getValue().compareTo(o2.getValue());
            // to compare alphabetically case insensitive return this instead
            // o1.getValue().toString().compareToIgnoreCase(o2.getValue().toString()); 
        }
    });

    //LinkedHashMap will keep the keys in the order they are inserted
    //which is currently sorted on natural ordering
    Map<K,V> sortedMap = new LinkedHashMap<K,V>();

    for(Map.Entry<K,V> entry: entries){
        sortedMap.put(entry.getKey(), entry.getValue());
    }

    return sortedMap;
}

чтобы вызвать этот метод, я использую:

Map<String, Integer> sorted = sortByValues(myOriginalHashMapObject);

подробнее: http://javarevisited.blogspot.com/2012/12/how-to-sort-hashmap-java-by-key-and-value.html#ixzz2akXStsGj


карты не могут быть упорядочены по значениям. Вы можете сделать это, хотя:

Collection<Student> students = map.values();

Collection.sort(new ArrayList<Student>(students)), new Comparator<Student>() {
    public int compare(Student s1, Student s2) {
        return s1.getName().compareTo(s2.getName());
    }
});

предполагая, конечно,что вам нужно перебирать значения. (Иначе зачем бы вы хотели, чтобы он был заказан таким образом?)

удачи.


HashMaps не могут быть отсортированы по их значениям. Карта предназначена для поиска постоянного времени на основе ключа, поэтому упорядочение по значениям не должно быть необходимым. Если вам нужно сортировать по имени, я предлагаю использовать SortedSet и создание компаратора, который сортирует по именам.

class StudentComparator implements Comparator<Student> {
    int compare(Student s1, Student s2) {
       return s1.getName().compareTo(s2.getName());
    }
}

Если вам нужен как постоянный поиск по времени, так и набор отсортированных по значению, вам может потребоваться сохранить карту и набор.


Я бы определенно использовал новый класс, который будет хранить ключ и объект.

затем вы можете поместить каждый элемент карты в ArrayList в виде этого класса и, наконец, использовать компаратор для сортировки ArrayList, после чего вы просто создадите новую карту. Код будет примерно такой:

Map<Object, Student> valueMap = new LinkedHashMap<String, String>();
List<Student> pairValueList = new ArrayList<PairValue>();

PairValue p;
for (Map.Entry<Object, Student> entry : map.entrySet()) {
  Object key = entry.getKey();
  Student value = entry.getValue();        
  p = new PairValue(key, value);
  pairValueList.add(p);
 }

Collections.sort(pairValueList, new Comparator<PairValue>() {
  @Override
  public int compare(PairValue c1, PairValue c2) {
    return c1.getLabel().compareTo(c2.getLabel());
  }
});

for (PairValue pv : pairValueList) {
  valueMap.put(pv.getValue(), pv.getStudent());
}

класс PairValue

    class PairValue {    

  private Object value;    
  private Student student;

  public PairValue(Object value, String student) {
    this.value = value;
    this.student= student;
  }

  public String getValue() {
    return value;
  }

  public String getStudent() {
    return student;
  }    
}

вот так я решил некоторую подобную проблему, которую я имел в прошлом. Обратите внимание, что возвращенная карта реализация должна быть LinkedHashMap.