在特定的顺序排序的数据(sorting data in specific order)

2019-10-29 18:10发布

在这里我ROWID的就象是下面

1

1.1

1.2

1.9

2

2.1

。 3。 。 9

9.9

10

10.1

List<MyBean> sortedList = rootItems.stream().sorted(Comparator.comparing(MyBean::getRowId)) .collect(Collectors.toList());

通过使用上面的代码我越来越像下面的输出。

1

10

11

12

2

2.1

2.2

但我要像下面的输出

1

1.1

1.1.1

1.1.1.1

1.2

1.3

1.9

10

11

2

2.1

2.2

2.3

3

3.1

3.2

4

9

9.1

9.2

9.9

10

10.1

这样就需要进行

如果我要像这里面设置我需要使用

Answer 1:

如果你归他们内部,要,然后可以排序的格式比较这些字符串会轻松很多。 我建议要垫零,像这样的个别项目:

private static final Pattern SINGLE_DIGIT = Pattern.compile("\\b(\\d)\\b");
...
String padWithZeroes = SINGLE_DIGIT.matcher(yourInputString).replaceAll("0$1");

现在只是排序的填充字符串。 这是假设的最高数量为2个位数,如果没有,我们将需要调整正则表达式和逻辑会稍微复杂一些。


如果任何数字段可超过2个位数越长,那么它会变得更加复杂。 下面是焊盘所有段的最大长度的方法:

static String padWithZeroes(String yourInputString, int digits) {
    final Matcher matcher = SINGLE_DIGIT.matcher(yourInputString);
    StringBuffer sb = new StringBuffer();
    while(matcher.find()){

        matcher.appendReplacement(sb, pad(digits - matcher.group().length())+matcher.group());
    }
    matcher.appendTail(sb);
    return sb.toString();
}

static String pad(int length) {
    final char[] chars = new char[length];
    Arrays.fill(chars, '0');
    return new String(chars);
}

这里的问题是,你必须知道的值digits前面的参数,所以要么你知道你的数据,或者你将不得不做,你测量最大长度单独的迭代。



Answer 2:

我没有尝试,我的电脑上,但似乎该数据不被转换到加倍的比较。 我认为加上mapToDouble(i->i.getRowId)之前排序会解决你的问题。



Answer 3:

正如我的评论已经指出的问题是,字符串是一个字符一个字符地进行比较。 因此就必须要么改变串,使得每个元件具有相等的长度,并且每个字符位置对应于其他ID的相同位置或分析元件成数字序列

替代1具有你需要具有用于每个分量(即一个,B,C以固定的最大长度的缺点abc等),或者你就必须先计算元件的数目。

选择2因而似乎是更好的,但是解析每个你比较他们时间字符串可能有点昂贵。 因此,你可能要为大家介绍的是代表你的ID和保存实际ID字符串以及分析版本的类。 这个类可以实现Comparable ,并仅在分析版本操作。

例:

class MyRowId implements Comparable<MyRowId> {
  private final String id;

  //when serializing instances of that class you might want to ignore this array 
  //and upon deserialization parse the string again
  private final int[] parsed;

  public MyRowId( String idString ) {
    id = idString;
    parsed = Arrays.stream( idString.split("\\.") ).mapToInt( Integer::parseInt ).toArray();
  }

  public int compareTo( MyRowId other )  {
    //Compare the elements one by one until we run out of elements or hit a difference
    //There might be a more Java8-ish way but I didn't find it yet
    for( int i = 0; i < Math.min( parsed.length, other.parsed.length ); i++ ) {
      int r = Integer.compare( parsed[i], other.parsed[i] );
      if( r != 0 ) {
        return r;
      }
    }

    //If we're here all compared elements were equal but one id might be longer so compare the lengths.
    //That would handle things like comparing "1.1" to "1.1.1" where the latter is greater.
    return Integer.compare( parsed.length, other.parsed.length );
  }
}


Answer 4:

使用自己的compare()这样的方法:

Collections.sort(myList, new Comparator<String>() {
    @Override
    public int compare(String id1, String id2) {
        double d1 = Double.parseDouble(id1);
        double d2 = Double.parseDouble(id2);
        return Double.compare(d1, d2);
    }
});

或者只是解析/ mapTo的ID为双和比较/排序它,然后。



Answer 5:

如果您指定了getRowId的返回类型()则实现可能会有所不同。


你可能需要做的是定义为类为myBean的比较器。 它可以实现为

  • 匿名类
  • λ表达式。

你的情况可能是:

class MyBeanComparator implements Comparator<MyBean>{
  public static final MyBeanComparator INSTANCE = new MyBeanComparator();
  public int compare(MyBean b1, MyBean b2){
         //your custom rules
      }
}

然后

List<MyBean> sortedList = rootItems.stream().sorted(MyBeanComparator.INSTANCE::compare) .collect(Collectors.toList());


文章来源: sorting data in specific order