How to sort Alphanumeric String with letters before numbers (ascending order)

huangapple go评论142阅读模式
英文:

How to sort Alphanumeric String with letters before numbers (ascending order)

问题

<p>我有一个带有以下顺序的字符串&lt;b&gt;ArrayList&lt;/b&gt;:</p>

```Collections.sort(alTest);```

1G0EE147546
1G1EE147576
1G3EE147547
1G4EE147577
1G6EE147548
1G6EE147574
1G7EE147578
1G8EE147545
1G9EE147575
1GXEE147579


<p>请注意最后一条记录1G&lt;b&gt;X&lt;/b&gt;EE147579,其中&quot;X&quot;在&quot;9&quot;之后,即1G&lt;b&gt;9&lt;/b&gt;EE147575。</p>

<p>我需要将此列表排序如下:</p>

1GXEE147579
1G0EE147546
1G1EE147576
1G3EE147547
1G4EE147577
1G6EE147548
1G6EE147574
1G7EE147578
1G8EE147545
1G9EE147575


<p>其中1G&lt;b&gt;X&lt;/b&gt;EE147579中的&quot;X&quot;位于数字&quot;0&quot;,&quot;1&quot;等之前,即1G&lt;b&gt;0&lt;/b&gt;EE147546。</p>

谢谢
英文:

<p>I have a <b>ArrayList</b> of Strings with this order:</p>

Collections.sort(alTest);

1G0EE147546
1G1EE147576
1G3EE147547
1G4EE147577
1G6EE147548
1G6EE147574
1G7EE147578
1G8EE147545
1G9EE147575
1GXEE147579

<p>Note the last record 1G<b>X</b>EE147579, when "X" comes after "9" 1G<b>9</b>EE147575.</p>

<p>And I need this list to be sorted this way:</p>

1GXEE147579
1G0EE147546
1G1EE147576
1G3EE147547
1G4EE147577
1G6EE147548
1G6EE147574
1G7EE147578
1G8EE147545
1G9EE147575

<p>With "X" of 1G<b>X</b>EE147579 before the numbers "0","1", etc. 1G<b>0</b>EE147546</p>

Thank you

答案1

得分: 2

你可以编写自己的比较器来调整排序条件以满足您的需求:

private static final Comparator<String> comparator = new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        //这里是比较过程
        return 0;
    }
};

比较器返回以下三个值之一:

  • -1,当o1对象在排序中应该位于o2对象之前
  • 1,当o1对象在排序中应该位于o2对象之后
  • 0,当比较的对象相等时。

然后您可以按以下方式使用它(请注意,要使用Collections.sort(...)函数,您必须使用列表结构):

Collections.sort(list, comparator);

为了对这个特定的排序提供一些提示,我可以建议您指定字符串中的每个字符是否应按照这种方式排序(字母在数字之前)。只需循环遍历字符串字符并进行比较。
要检查字符是否为数字,请使用Character.isDigit(...)

英文:

You can write your own comparator to adjust sorting condition to your requirements:

    private static final Comparator&lt;String&gt; comparator = new Comparator&lt;String&gt;() {
        @Override
        public int compare(String o1, String o2) {
            //here comes the comparing process
            return 0;
        }
    };

Comparator returns one of three values:

  • -1 when the o1 object should be placed before o2 in order
  • 1 when the o1 object should be placed after o2 in order
  • 0 when comparing objects are equal

Then you can use it in that way(notice that to use Collections.sort(...) function you have to use list structure):

        Collections.sort(list, comparator);

To give some hint about this specific sort I can recommend you to specify whether every character in string should be sorted in that way(letters before numbers). Just loop over string characters and compare them.
To check if character is a digit use Character.isDigit(...).

答案2

得分: 2

这里有一个简单的比较器示例,可以实现你想要的功能。

编辑:你还可以将比较器添加到你的集合中,作为 TreeSet 而不是 HashSet

Set<String> datas = new TreeSet<>(new SimpleComparator());

你可以参考 javadoc 获取更多详细信息。

    static class SimpleComparator implements Comparator<String> {
        @Override
        public int compare(String s, String s2)
        {
            if(s == s2)
                return 0;
            if(s != null && s2 == null)
                return -1;
            if(s == null && s2 != null)
                return 1;
            return (s.charAt(2) == 'X' ? s.substring(0, 2) + ' ' + s.substring(3) : s).compareTo(s2);
        }
    }

    @Test
    public void sort() throws Exception{

        List<String> data =  Arrays.asList(
                "1G0EE147546",
                "1G1EE147576",
                "1G3EE147547",
                "1G4EE147577",
                "1G6EE147548",
                "1G6EE147574",
                "1G7EE147578",
                "1G8EE147545",
                "1G9EE147575",
                "1GXEE147579"

        );
        Collections.sort(data, new SimpleComparator());
        System.out.println(data.toString().replaceAll(",", "\n"));
    }
英文:

Here a simple comparator example to do what you want.

Edit : You can also add the comparator to you Set as a TreeSet instead of HashSet.

Set&lt;String&gt; datas = new TreeSet&lt;&gt;(new SimpleComparator());

You can refers to the javadoc for more details

    static class SimpleComparator implements Comparator&lt;String&gt; {
        @Override
        public int compare(String s, String s2)
        {
            if(s == s2)
                return 0;
            if(s != null &amp;&amp; s2 == null)
                return -1;
            if(s == null &amp;&amp; s2 != null)
                return 1;
            return (s.charAt(2) == &#39;X&#39; ? s.substring(0, 2) + &#39; &#39; + s.substring(3) : s).compareTo(s2);
        }
    }

    @Test
    public void sort() throws Exception{

        List&lt;String&gt; data =  Arrays.asList(
                &quot;1G0EE147546&quot;,
                &quot;1G1EE147576&quot;,
                &quot;1G3EE147547&quot;,
                &quot;1G4EE147577&quot;,
                &quot;1G6EE147548&quot;,
                &quot;1G6EE147574&quot;,
                &quot;1G7EE147578&quot;,
                &quot;1G8EE147545&quot;,
                &quot;1G9EE147575&quot;,
                &quot;1GXEE147579&quot;

        );
        Collections.sort(data, new SimpleComparator());
        System.out.println(data.toString().replaceAll(&quot;,&quot;, &quot;\n&quot;));
    }

答案3

得分: 1

以下是翻译好的部分:

这里是一些输入:

  1. 你无法对 HashSet 进行排序。Collections#sort 处理的是 List。你可以创建一个 ArrayList,将 Set 传递给构造函数:
Set<String> hsNr = new HashSet<String>();
ArrayList list = new ArrayList(hsNr);
  1. 要按照你需要的方式对列表进行排序,你可以将 Comparator 作为 Collections#sort 的第二个参数传递:
Collections.sort(list, new Comparator<String>() {
    public int compare(String o1, String o2) {
        // 在这里编写你的实现
        // 返回 ...
    }
});
  1. 你可以查看字符串比较的标准实现,并将其用作创建 Comparator 的示例:java.lang.StringUTF16#compareTo(byte[], byte[])
英文:

Here are some inputs:

  1. You can't sort HashSet. Collections#sort consumes List. You can create the ArrayList passing the Set into Constructor
Set&lt;String&gt; hsNr = new HashSet&lt;String&gt;();
ArrayList list = new ArrayList(hsNr);
  1. For sorting the list the way you need you can pass Comparator as 2nd param to Collections#sort:
        Collections.sort(list, new Comparator&lt;String&gt;() {
            public int compare(String o1, String o2) {
                // write your implementation here
                // return ...  
            }
        });
  1. You can take take a look at the standard impl on strings comparing and use it as example to create the Comparator: java.lang.StringUTF16#compareTo(byte[], byte[])

答案4

得分: 1

我使用Java 8的流实现了它:

public List<String> specialSort(Set<String> hsNr) {
    return hsNr.stream()
            .sorted((a, b) -> a.charAt(2) == 'X' ? b.compareTo(a) : a.compareTo(b))
            .collect(Collectors.toList());
}

由于集合(Sets)无法保证顺序,因此无法对其进行排序。请注意,在使用集合时,没有get(index)方法。

英文:

I implemented it using Java 8 streams:

    public List&lt;String&gt; specialSort(Set&lt;String&gt; hsNr) {
return hsNr.stream()
.sorted((a, b) -&gt; a.charAt(2) == &#39;X&#39; ? b.compareTo(a) : a.compareTo(b))
.collect(Collectors.toList());
}

Sets can't be sorted, because order is not guaranteed. Notice that you don't have a get(index) method when working with a set.

答案5

得分: 1

使用 RuleBasedCollator 类创建自定义 Collator

String rules = "< a, A < b, B < c, C < d, D < e, E < f, F < g, G < h, H < i, I" +
" < j, J < k, K < l, L < m, M < n, N < o, O < p, P < q, Q < r, R" +
" < s, S < t, T < u, U < v, V < w, W < x, X < y, Y < z, Z" +
" < 0 < 1 < 2 < 3 < 4 < 5 < 6 < 7 < 8 < 9";
RuleBasedCollator myCollator = new RuleBasedCollator(rules);
List<String> list = Arrays.asList(
"1G7EE147578", "1G6EE147548", "1G1EE147576", "1G0EE147546", "1G8EE147545",
"1G4EE147577", "1G6EE147574", "1GXEE147579", "1G9EE147575", "1G3EE147547");
System.out.println("Before: " + list);
Collections.sort(list, myCollator);
System.out.println("After:  " + list);

输出

Before: [1G7EE147578, 1G6EE147548, 1G1EE147576, 1G0EE147546, 1G8EE147545, 1G4EE147577, 1G6EE147574, 1GXEE147579, 1G9EE147575, 1G3EE147547]
After:  [1GXEE147579, 1G0EE147546, 1G1EE147576, 1G3EE147547, 1G4EE147577, 1G6EE147548, 1G6EE147574, 1G7EE147578, 1G8EE147545, 1G9EE147575]
英文:

Create a custom Collator using the RuleBasedCollator class:

String rules = &quot;&lt; a, A &lt; b, B &lt; c, C &lt; d, D &lt; e, E &lt; f, F &lt; g, G &lt; h, H &lt; i, I&quot; +
&quot; &lt; j, J &lt; k, K &lt; l, L &lt; m, M &lt; n, N &lt; o, O &lt; p, P &lt; q, Q &lt; r, R&quot; +
&quot; &lt; s, S &lt; t, T &lt; u, U &lt; v, V &lt; w, W &lt; x, X &lt; y, Y &lt; z, Z&quot; +
&quot; &lt; 0 &lt; 1 &lt; 2 &lt; 3 &lt; 4 &lt; 5 &lt; 6 &lt; 7 &lt; 8 &lt; 9&quot;;
RuleBasedCollator myCollator = new RuleBasedCollator(rules);
List&lt;String&gt; list = Arrays.asList(
&quot;1G7EE147578&quot;, &quot;1G6EE147548&quot;, &quot;1G1EE147576&quot;, &quot;1G0EE147546&quot;, &quot;1G8EE147545&quot;,
&quot;1G4EE147577&quot;, &quot;1G6EE147574&quot;, &quot;1GXEE147579&quot;, &quot;1G9EE147575&quot;, &quot;1G3EE147547&quot;);
System.out.println(&quot;Before: &quot; + list);
Collections.sort(list, myCollator);
System.out.println(&quot;After:  &quot; + list);

Output

Before: [1G7EE147578, 1G6EE147548, 1G1EE147576, 1G0EE147546, 1G8EE147545, 1G4EE147577, 1G6EE147574, 1GXEE147579, 1G9EE147575, 1G3EE147547]
After:  [1GXEE147579, 1G0EE147546, 1G1EE147576, 1G3EE147547, 1G4EE147577, 1G6EE147548, 1G6EE147574, 1G7EE147578, 1G8EE147545, 1G9EE147575]

huangapple
  • 本文由 发表于 2020年10月28日 01:02:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/64559399.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定