2017-01-26 3 views
-6

У меня есть объект персонажа, который имеет имя в качестве атрибута. У меня есть treemap, который связывает человека с расстоянием, которое является целым числом.Сортировка TreeMap в алфавитном порядке

Мне нужно отсортировать TreeMap в алфавитном порядке, взглянув на имя каждого человека в нем.

Как я могу это сделать? Благодарим вас за ответы.

+8

Возможный дубликат [Java TreeMap Компаратор] (http://stackoverflow.com/questions/12947088/java-treemap-comparator) – Idos

+0

Пожалуйста, попытайтесь создать [Минимальный, полный и проверенный пример] (http://stackoverflow.com/help/mcve) и покажите нам, что вы уже пробовали. –

+1

TreeMap сортируется по его клавишам. Каков тип каждого ключа в вашей TreeMap? – VGR

ответ

1

Эрик Берри написал удобный класс, который сравнивает строки по человеческим значениям вместо традиционных значений машины. Ниже приведена модифицированная версия вместе с объектным компаратором (что, как я думаю, вы ищите), и его классом тестирования.

Пример того, как использовать строку компаратор:

Map<String,String> humanSortedMap = new TreeMap<>(new AlphaNumericStringComparator()); 

пример того, как использовать объект компаратор, но на этот раз с помощью списка вместо TreeMap:

Collections.sort(humanSortedList, new AlphaNumericObjectComparator<QuartzJobWrapper>() 
      { 
       @Override 
       public int compare(QuartzJobWrapper t1, QuartzJobWrapper t2) 
       { 
        return compareStrings(t1.getName(), t2.getName()); 
       } 
      }); 

AlphaNumericStringComparator Источник:

/* 
* Copyright (c) 2007 Eric Berry <[email protected]> 
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy 
* of this software and associated documentation files (the "Software"), to deal 
* in the Software without restriction, including without limitation the rights 
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
* copies of the Software, and to permit persons to whom the Software is 
* furnished to do so, subject to the following conditions: 
* 
* The above copyright notice and this permission notice shall be included in 
* all copies or substantial portions of the Software. 
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
* THE SOFTWARE. 
*/ 

import java.text.DecimalFormatSymbols; 
import java.util.Comparator; 
import java.util.Locale; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

import org.apache.commons.lang3.StringUtils; 

/** 
* Compares Strings by human values instead of traditional machine values. 
* 
* @author elberry 
* @modified Tristan Everitt 
*/ 
public class AlphaNumericStringComparator implements Comparator<String> 
{ 

    private Pattern alphaNumChunkPattern; 

    public AlphaNumericStringComparator() 
    { 
     this(Locale.getDefault()); 
    } 

    public AlphaNumericStringComparator(Locale locale) 
    { 
     DecimalFormatSymbols dfs = new DecimalFormatSymbols(locale); 
     char localeDecimalSeparator = dfs.getDecimalSeparator(); 
     // alphaNumChunkPatter initialized here to get correct decimal separator for locale. 
     alphaNumChunkPattern = Pattern.compile("(\\d+\\" + localeDecimalSeparator + "\\d+)|(\\d+)|(\\D+)"); 
    } 

    @Override 
    public int compare(String s1, String s2) 
    { 
     int compareValue = 0; 
     Matcher s1ChunkMatcher = alphaNumChunkPattern.matcher(s1); 
     Matcher s2ChunkMatcher = alphaNumChunkPattern.matcher(s2); 
     String s1ChunkValue = null; 
     String s2ChunkValue = null; 

     while (s1ChunkMatcher.find() && s2ChunkMatcher.find() && compareValue == 0) 
     { 
      s1ChunkValue = s1ChunkMatcher.group(); 
      s2ChunkValue = s2ChunkMatcher.group(); 

      // teveritt - Remove white space and make lower case to neutralise it 
      s1ChunkValue = s1ChunkValue.replaceAll("\\s+", ""); 
      s2ChunkValue = s2ChunkValue.replaceAll("\\s+", ""); 
      s1ChunkValue = StringUtils.lowerCase(s1ChunkValue); 
      s2ChunkValue = StringUtils.lowerCase(s2ChunkValue); 

      try 
      { 
       // compare double values - ints get converted to doubles. Eg. 100 = 100.0 
       Double s1Double = Double.valueOf(s1ChunkValue); 
       Double s2Double = Double.valueOf(s2ChunkValue); 
       compareValue = s1Double.compareTo(s2Double); 
      } 
      catch (NumberFormatException e) 
      { 
       // not a number, use string comparison. 
       compareValue = s1ChunkValue.compareTo(s2ChunkValue); 
      } 
      // if they are equal thus far, but one has more left, it should come after the one that doesn't. 
      if (compareValue == 0) 
      { 
       if (s1ChunkMatcher.hitEnd() && !s2ChunkMatcher.hitEnd()) 
       { 
        compareValue = -1; 
       } 
       else if (!s1ChunkMatcher.hitEnd() && s2ChunkMatcher.hitEnd()) 
       { 
        compareValue = 1; 
       } 
      } 
     } 
     return compareValue; 
    } 
} 

AlphaNumericObjectComparator Источник:

/** 
* Compares Objects by human values instead of traditional machine values. 
* 
* @modified Tristan Everitt 
*/ 
public class AlphaNumericObjectComparator<T> implements Comparator<T> 
{ 

    private AlphaNumericStringComparator stringComparator; 

    public AlphaNumericObjectComparator() 
    { 
     this(Locale.getDefault()); 
    } 

    public AlphaNumericObjectComparator(Locale locale) 
    { 
     this.stringComparator = new AlphaNumericStringComparator(locale); 
    } 

    @Override 
    public int compare(T t1, T t2) 
    { 
     return compareStrings(t1.toString(), t2.toString()); 
    } 

    protected int compareStrings(String s1, String s2) 
    { 
     return stringComparator.compare(s1, s2); 
    } 
} 

AlphaNumericStringComparatorTester Источник:

import static org.junit.Assert.assertEquals; 
import static org.junit.Assert.assertNotEquals; 

import java.util.Arrays; 
import java.util.Collections; 
import java.util.List; 
import java.util.Random; 

import org.junit.Test; 

/** 
* 
* @author Tristan Everitt 
*/ 
public class AlphaNumericStringComparatorTester 
{ 
    @Test 
    public void testHumanNaturalSort1() 
    { 
     List<String> randomList = Arrays.asList("z1.doc", "z10.doc", "z100.doc", "z101.doc", "z102.doc", "z11.doc", "z12.doc", "z13.doc", "z14.doc", "z15.doc", "z16.doc", "z17.doc", "z18.doc", 
       "z19.doc", "z2.doc", "z20.doc", "z3.doc", "z4.doc", "z5.doc", "z6.doc", "z7.doc", "z8.doc", "z9.doc", "z1.2.doc", "z1.3.doc"); 
     Collections.shuffle(randomList, new Random()); 

     List<String> expected = Arrays.asList("z1.doc", "z1.2.doc", "z1.3.doc", "z2.doc", "z3.doc", "z4.doc", "z5.doc", "z6.doc", "z7.doc", "z8.doc", "z9.doc", "z10.doc", "z11.doc", "z12.doc", 
       "z13.doc", "z14.doc", "z15.doc", "z16.doc", "z17.doc", "z18.doc", "z19.doc", "z20.doc", "z100.doc", "z101.doc", "z102.doc"); 

     assertNotEquals(expected, randomList); 
     Collections.sort(randomList, new AlphaNumericStringComparator()); 
     assertEquals(expected, randomList); 
    } 

    @Test 
    public void testHumanNaturalSort2() 
    { 
     List<String> randomList = Arrays.asList("z1.doc", "z10.doc", "z100.doc", "z101.doc", "z102.doc", "z11.doc", "z12.doc", "z13.doc", "z14.doc", "z15.doc", "z16.doc", "z17.doc", "z18.doc", 
       "z19.doc", "z2.doc", "z20.doc", "z3.doc", "z4.doc", "z5.doc", "z6.doc", "z7.doc", "z8.doc", "z9.doc", "z1.2.doc", "z1.3.doc"); 
     Collections.shuffle(randomList, new Random()); 

     List<String> expected = Arrays.asList("z1.doc", "z1.2.doc", "z1.3.doc", "z2.doc", "z3.doc", "z4.doc", "z5.doc", "z6.doc", "z7.doc", "z8.doc", "z9.doc", "z10.doc", "z11.doc", "z12.doc", 
       "z13.doc", "z14.doc", "z15.doc", "z16.doc", "z17.doc", "z18.doc", "z19.doc", "z20.doc", "z100.doc", "z101.doc", "z102.doc"); 

     assertNotEquals(expected, randomList); 
     Collections.sort(randomList, new AlphaNumericStringComparator()); 
     assertEquals(expected, randomList); 
    } 

    @Test 
    public void testHumanNaturalSort3() 
    { 
     List<String> randomList = Arrays.asList("yr1", "yr10", "yr11", "yr12", "yr13", "yr2", "yr 3", "yr 3.4", "yr 4", "yr5", "yr6", "yr7", "yr8", "yr 9"); 
     Collections.shuffle(randomList, new Random()); 

     List<String> expected = Arrays.asList("yr1", "yr2", "yr 3", "yr 3.4", "yr 4", "yr5", "yr6", "yr7", "yr8", "yr 9", "yr10", "yr11", "yr12", "yr13"); 

     assertNotEquals(expected, randomList); 
     Collections.sort(randomList, new AlphaNumericStringComparator()); 
     assertEquals(expected, randomList); 
    } 

    @Test 
    public void testHumanNaturalSort4() 
    { 
     List<String> randomList = Arrays.asList("1-2", "1-02", "1-20", "10-20", "fred", "jane", "pic01", "pic2", "pic02", "pic02a", "pic3", "pic4", "pic 4 else", "pic 5", "pic05", "pic 5", 
       "pic 5 something", "pic 6", "pic 7", "pic100", "pic100a", "pic120", "pic121", "pic02000", "tom", "x2-g8", "x2-y7", "x2-y08", "x8-y8"); 
     Collections.shuffle(randomList, new Random()); 

     List<String> expected = Arrays.asList("1-2", "1-02", "1-20", "10-20", "fred", "jane", "pic01", "pic02", "pic2", "pic02a", "pic3", "pic4", "pic 4 else", "pic 5", "pic05", "pic 5", 
       "pic 5 something", "pic 6", "pic 7", "pic100", "pic100a", "pic120", "pic121", "pic02000", "tom", "x2-g8", "x2-y7", "x2-y08", "x8-y8"); 

     assertNotEquals(expected, randomList); 
     Collections.sort(randomList, new AlphaNumericStringComparator()); 
     assertEquals(expected, randomList); 
    } 

} 
Смежные вопросы