Java List 根据整数排序,带有多个下划线的情况

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

Java List String sort Based on Integer with multiple underscore's

问题

你好,你可以使用Java 8中的lambda表达式和Comparator来实现这个排序逻辑。以下是你的代码片段的排序实现:

keyValues.sort(Comparator.comparing(s -> Arrays.asList(s.split("_"))
        .stream()
        .map(Integer::parseInt)
        .collect(Collectors.toList())));

这将按照你描述的逻辑对keyValues进行排序。

英文:

Hi All I have arrayList of String datatype but needs to sort like integer with multiple underscore's using Java 8 only ,For your reference I have added sample data, the original data came Liferay 7.1 DDL

List<String> keyValues = new ArrayList<String>();
keyValues.add("100_10_20_1");
keyValues.add("100001");
keyValues.add("100002");
keyValues.add("100002_1");
keyValues.add("100003");
keyValues.add("100");
keyValues.add("100_1");
keyValues.add("100_2");
keyValues.add("100_1_1");
keyValues.add("100_10_20");
keyValues.add("10000001");
keyValues.add("100_10_20_2");

i tried to replace the underscore with 0 but what happens sometimes 100_1 replace _ with 0 then it becomes 10001 but what if i already have 10001 value present in list ? even same thing for empty if i replace _ with "" then it becomes 1001 but what if i already have 1001 then again i am facing issue

Exact logic based on underscore was

 100
 100_1
 100_1_2 
 /after that only/
 100_2
 100_2_2
/after that/
 103
 104
 105
 10000
/similarly the pattern repeats/
 10000_1
 10000_2
 10000_2_1
 100002

i need the exact output as

    100
    100_1
    100_1_1
    100_2
    100_10_20
    100_10_20_1
    100_10_20_2
    100001
    100002
    100002_1
    100003
    10000001

i tried with replacing underscore with 0 or empty space but there is possiblity of if it had already that number present in list,if i replace with dot and storing as Double then multiple pointer exception will occur

答案1

得分: 4

我创建了一个比较器,然后根据每个字符串具有的最小标记数量进行分割和处理。

static Comparator<String> stringComparator = new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        String[] s1 = o1.split("_");
        String[] s2 = o2.split("_");

        int minLen = Math.min(s1.length, s2.length);

        for (int i=0; i < minLen; i++){
            if (!s1[i].equals(s2[i])){
                return Integer.parseInt(s1[i]) - Integer.parseInt(s2[i]);
            }
        }

        return o1.compareTo(o2);
    }
};

调用方式如下:

List<String> keyValues = new ArrayList<String>();
keyValues.add("100001");
keyValues.add("100002");
keyValues.add("100002_1");
keyValues.add("100003");
keyValues.add("100");
keyValues.add("100_1");
keyValues.add("100_2");
keyValues.add("100_1_1");
keyValues.add("100_10_20");
keyValues.add("10000001");
keyValues.stream().sorted(stringComparator).forEach(System.out::println);

输出结果:

100
100_1
100_1_1
100_2
100_10_20
100001
100002
100002_1
100003
10000001
英文:

I made a comparator then split the string and process based on the min amount of tokens each string has.

static Comparator&lt;String&gt; stringComparator = new Comparator&lt;String&gt;() {
        @Override
        public int compare(String o1, String o2) {
            String[] s1 = o1.split(&quot;_&quot;);
            String[] s2 = o2.split(&quot;_&quot;);

            int minLen = Math.min(s1.length, s2.length);

            for (int i=0; i &lt; minLen; i++){
                if (!s1[i].equals(s2[i])){
                    return Integer.parseInt(s1[i]) - Integer.parseInt(s2[i]);
//                    return s1[i].compareTo(s2[i]);  //not natural order/sort
                }
            }

            return o1.compareTo(o2);
        }
    };

Calling it like so:

    List&lt;String&gt; keyValues = new ArrayList&lt;String&gt;();
    keyValues.add(&quot;100001&quot;);
    keyValues.add(&quot;100002&quot;);
    keyValues.add(&quot;100002_1&quot;);
    keyValues.add(&quot;100003&quot;);
    keyValues.add(&quot;100&quot;);
    keyValues.add(&quot;100_1&quot;);
    keyValues.add(&quot;100_2&quot;);
    keyValues.add(&quot;100_1_1&quot;);
    keyValues.add(&quot;100_10_20&quot;);
    keyValues.add(&quot;10000001&quot;);
    keyValues.stream().sorted(stringComparator).forEach(System.out::println);

Gives output:

100
100_1
100_1_1
100_2
100_10_20
100001
100002
100002_1
100003
10000001

huangapple
  • 本文由 发表于 2023年5月10日 17:57:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76217086.html
匿名

发表评论

匿名网友

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

确定