按字母顺序排序TreeMap

时间:2017-01-26 13:33:20

标签: java sorting treemap alphabetical

我有一个typer person的对象,它有一个名称作为属性。 我有一个树形图,它将人与一个距离相连,这是一个整数。

我需要按字母顺序对TreeMap进行排序,方法是查看其中每个人的姓名。

我该怎么做? 谢谢你的回答。

1 个答案:

答案 0 :(得分:1)

Eric Berry写了一个方便的课程,用人类价值观比较字符串,而不是传统的机器价值。下面是它的修改版本以及Object比较器(我认为你正在寻找的)及其测试类。

关于如何使用字符串比较器的示例:

Ciper Text : ef/ENVlBn9QBFlkvoN7P2Q==
Plain Text after decryption : Hello

关于如何使用对象比较器的示例,但这次使用的是List而不是TreeMap:

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

AlphaNumericStringComparator来源:

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

AlphaNumericObjectComparator来源:

  /*
 * Copyright (c) 2007 Eric Berry <elberry@gmail.com>
 *
 * 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;
    }
}

AlphaNumericStringComparatorTester来源:

/**
 * 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);
    }
}