在这里我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
。
。
这样就需要进行
如果我要像这里面设置我需要使用
如果你归他们内部,要,然后可以排序的格式比较这些字符串会轻松很多。 我建议要垫零,像这样的个别项目:
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
前面的参数,所以要么你知道你的数据,或者你将不得不做,你测量最大长度单独的迭代。
我没有尝试,我的电脑上,但似乎该数据不被转换到加倍的比较。 我认为加上mapToDouble(i->i.getRowId)
之前排序会解决你的问题。
正如我的评论已经指出的问题是,字符串是一个字符一个字符地进行比较。 因此就必须要么改变串,使得每个元件具有相等的长度,并且每个字符位置对应于其他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 );
}
}
使用自己的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为双和比较/排序它,然后。
如果您指定了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());