2011-12-25 5 views
1

У меня есть карта, что я хочу, чтобы отсортировать его содержимое в соответствии с некоторыми правилами:Сортировка карта в соответствии с некоторыми правилами

  1. Сортировать карту в алфавитном порядке (от А до Z) в соответствии с его значениями и не его Ключи.
  2. Игнорировать регистр Чувствительность значений при их сортировке.
  3. Учитывайте повторяющиеся слова (слова с точными буквами) Написание & Корпус).
  4. Сортировка буквенных цифр в алфавите (Cbc2ee должно появиться до Cbc100ee).
  5. Обращение с английскими словами (área должно появляться в словах, начинающихся с буквы «a», но на самом деле оно появляется после слов, начинающихся с буквы «z», с учетом другой буквы).

Я думаю, что я хочу, все логично. Я был в состоянии выполнить пункты 1, 2 & 3 через этот код:

public <K, V extends Comparable<? super V>> LinkedHashMap<K, V> sortMapByValues(Map<K, V> map) { 
    SortedSet<Map.Entry<K, V>> sortedEntries = new TreeSet<Map.Entry<K, V>>(
     new Comparator<Map.Entry<K, V>>() { 
      @Override 
      public int compare(Map.Entry<K, V> e1, Map.Entry<K, V> e2) { 
       String a = (String)e1.getValue(); 
       String b = (String)e2.getValue(); 

       int diff = a.compareToIgnoreCase(b); 

       if (diff == 0) 
        diff = a.compareTo(b); 

       return diff != 0 ? diff : 1; // Special fix to preserve words with similar spelling. 
      } 
     } 
    ); 

    sortedEntries.addAll(map.entrySet()); 

    LinkedHashMap<K, V> sortedMap = new LinkedHashMap<K, V>(); 

    for(Map.Entry<K, V> sortedEntry : sortedEntries) 
     sortedMap.put(sortedEntry.getKey(), sortedEntry.getValue()); 

    return sortedMap; 
} 

Point (4) я нашел сценарий для него, но я не мог объединить его с моим кодом: http://www.davekoelle.com/alphanum.html

Поинт (5) также я нашел для этого сценарий, но я не смог объединить его с моим кодом: http://www.javapractices.com/topic/TopicAction.do?Id=207

Поскольку эти моменты повлияют на метод сравнения (...). Любой может мне помочь?

+1

Кажется мне, что на самом деле решение 4 и 5 вместо этого решит 1, 2, 3. Способ сделать это - использовать скрипт с 4, а затем заменить механизм сортировки вторым примером из 5. – Kraylog

+0

Код, который вы нашли для Point (4), прямо на деньги, и код, который вы нашли для Point (5), также стоит на деньги. Если вы не можете объединить их в свой код, вам нужно лучше ознакомиться с языком Java. Переполнение стека предназначено для вопросов о конкретных вещах и ответа на них; он не предназначен для того, чтобы попросить людей написать свой код для вас. –

+0

Конечно, у вас всегда могут быть прославленные шлюхи, которые пишут ваш код для вас, заманивая их обильной щедростью. –

ответ

1

Пар точек ...

Метод подпись должна быть:

public static <K, V> Map<K, V> sortMapByValues(Map<K, V> map) 

Примечание: - Удаление связанного с Comparable, потому что вы сравниваете toString() значений карты , а не сами значения - Спецификация абстрактного типа Map<...>, а не бетон LinkedHashMap, согласно хорошим руководящим принципам проектирования - static, потому что он не изменить состояние - это «только код»

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

Вот код, который должен делать то, что вы хотите:

public static <K, V> Map<K, V> sortMapByValues(Map<K, V> map) { 
    SortedSet<Map.Entry<K, V>> sortedEntries = new TreeSet<Map.Entry<K, V>>(new Comparator<Map.Entry<K, V>>() { 
     public int compare(Map.Entry<K, V> e1, Map.Entry<K, V> e2) { 
      String aRaw = e1.getValue().toString(); 
      String bRaw = e2.getValue().toString(); 
      String a = standardize(aRaw); 
      String b = standardize(bRaw); 

      // Check for hex 
      try 
      { 
       Integer ai = Integer.parseInt(a, 16); 
       Integer bi = Integer.parseInt(b, 16); 
       int diff = ai.compareTo(bi); 
       if (diff != 0) 
        return diff; 
      } 
      catch (NumberFormatException ignore) 
      { 
      } 

      int diff = a.compareTo(b); 
      if (diff != 0) 
       return diff; 
      return aRaw.compareTo(bRaw); 
     } 

     /** This method removes all accent (diacritic) marks and changes to lower case */ 
     String standardize(String input) { 
      StringBuilder sb = new StringBuilder(); 
      for (int i = 0; i < input.length(); i++) { 
       char c = input.charAt(i); 
       sb.append(Normalizer.normalize(c + "", Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", "")); 
      } 
      return sb.toString().toLowerCase(); 
     } 
    }); 

    // The rest is your code left as it was, cos it's fine 
    sortedEntries.addAll(map.entrySet()); 

    LinkedHashMap<K, V> sortedMap = new LinkedHashMap<K, V>(); 

    for (Map.Entry<K, V> sortedEntry : sortedEntries) 
     sortedMap.put(sortedEntry.getKey(), sortedEntry.getValue()); 

    return sortedMap; 
} 

Вот код теста:

public static void main(String[] args) { 
    Map<String, String> map = new HashMap<String, String>(); 
    map.put("a", "CC96"); 
    map.put("b", "CC97"); 
    map.put("c", "CC102"); 
    map.put("d", "CC103"); 
    map.put("e", "aabbcc"); 
    map.put("f", "aabbCC"); 
    map.put("g", "atabends"); 
    map.put("h", "aaBBcc"); 
    map.put("i", "AABBcc"); 
    map.put("j", "aabbcc"); 
    map.put("k", "Cc102"); 
    map.put("l", "baldmöglichst"); 
    map.put("m", "bar"); 
    map.put("n", "barfuss"); 
    map.put("o", "barfuß"); 
    map.put("p", "spätabends"); 
    map.put("q", "ätabends"); 
    map.put("r", "azebra"); 

    System.out.println(sortMapByValues(map).toString() 
     .replaceAll(", ", "\r").replaceAll("(\\{|\\})", "")); 
} 

Выход:

a=CC96 
b=CC97 
c=CC102 
k=Cc102 
d=CC103 
i=AABBcc 
h=aaBBcc 
f=aabbCC 
e=aabbcc 
g=atabends 
q=ätabends 
r=azebra 
l=baldmöglichst 
m=bar 
n=barfuss 
o=barfuß 
p=spätabends 
+0

@Bohemain: Спасибо за хорошее решение, особенно для стандартизации (...) метода. Он просто пропускает обработку повторяющихся слов, таких как (CC102, Cc102, aaBBcc, AABBcc, aabbcc). Сценарий будет принимать только один экземпляр дублированного слова и игнорировать остальные. Даже если вы учитываете чувствительность к регистру слов, сортировка слов может показаться неправильной. Вот полный список слов, которые я тестировал: (CC96, CC97, CC102, CC103, aabbcc, aabbCC, atabends, aaBBcc, AABBcc, aabbcc, Cc102, baldmöglichst, bar, barfuss, barfuß, spätabends, ätabends, azebra) – Brad

+0

I не понимаете, что вы подразумеваете под «игнорированием». Карты имеют ключи и значения - какие именно ключи и значения вы вставляете в карту, передаваемую методу sortMapByValues? – Bohemian

+0

@Bohemain: Ключами могут быть любые уникальные идентификаторы, поэтому карта будет выглядеть следующим образом: [a: CC96, b: CC97, c: CC102, d: CC103, e: aabbcc, f: aabbCC, g: atabends, h: aaBBcc , i: AABBcc, j: aabbcc, k: Cc102, l: baldmöglichst, m: bar, n: barfuss, o: barfuß, p: spätabends, q: ätabends, r: azebra]. Теперь, если я сортирую значения этой карты с помощью вашего кода, это приведет к: [atabends, azebra, baldmöglichst, bar, barfuss, barfuß, CC96, CC97, CC102, CC103, aabbcc, spätabends]. – Brad