按字母顺序对TreeMap进行排序

鲁本·莱泽沃维奇

我有一个打字机人员的对象,该对象具有一个名称作为属性。我有一个树形图,将人链接到一个整数距离。

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

我怎样才能做到这一点 ?谢谢您的回答。

特里斯坦·埃弗里特(Tristan Everitt)

埃里克·贝里(Eric Berry)编写了一个方便的类,该类通过人为值(而不是传统机器值)比较字符串。下面是它的修改版本以及对象比较器(我认为您正在寻找的内容)及其测试类。

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

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

}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

按字母顺序对ListView的元素进行排序

来自分类Dev

Android按字母顺序对ListView进行排序

来自分类Dev

MySQL按字母顺序对记录进行排序

来自分类Dev

按字母顺序对组合框进行排序

来自分类Dev

按字母顺序对字典进行排序

来自分类Dev

按字母顺序对TableView进行重新排序

来自分类Dev

按字母顺序对搜索结果进行排序

来自分类Dev

按字母顺序对NSArray进行排序

来自分类Dev

Android按字母顺序对ListView进行排序

来自分类Dev

按字母顺序对单词进行排序

来自分类Dev

按字母顺序对选择进行排序

来自分类Dev

按字母顺序对组合框进行排序

来自分类Dev

按字母顺序对XML进行排序

来自分类Dev

如何按字母顺序对LinkedList进行排序?

来自分类Dev

按字母顺序对TableView进行重新排序

来自分类Dev

PHP:按字母顺序对 ZIP 进行排序

来自分类Dev

按字母顺序对多个列表进行排序

来自分类Dev

按项目对列表进行排序,按字母顺序排序

来自分类Dev

如何按字母顺序对字母数字列表进行排序

来自分类Dev

按字母顺序对文本中的字母出现进行排序

来自分类Dev

按出现顺序和字母顺序对列表进行排序

来自分类Dev

在QStandardItemModel中按字母顺序对列进行排序:QSortFilterProxyModel

来自分类Dev

如何按字母顺序对字符串的ArrayList进行排序?

来自分类Dev

按字母顺序对名称的链接列表进行排序

来自分类Dev

使用JavaScript按字母顺序对丹麦语进行排序?

来自分类Dev

如何按字母顺序对Ruby Hash进行排序

来自分类Dev

MongoDB按字母顺序对输出进行排序(分组后)

来自分类Dev

如何按字母顺序对模板中的对象列表进行排序?

来自分类Dev

按字母顺序对对象的ArrayList进行排序

Related 相关文章

热门标签

归档