按对象字段对列表进行字母数字排序<object>



我有List<Object>。每个Object都有Number(String)的性质。我需要根据number字段字母数字对objectslist进行排序。

public class Object{
private String number;
}

数字可以是(例如):

#3772-BOZ-007
#3772-BAZ-02
#31-002
#001

每个数字都以#开头我已经尝试过了,但失败了:

lstObjects.sort(Comparator.naturalOrder());

您需要实现Comparable<>. compareto方法。

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class Obj implements Comparable<Obj> {
private String number;
public Obj(String number) {
this.number = number;
}
@Override
public int compareTo(Obj o2) {
int i1 = numPart();
int i2 = o2.numPart();
if (i1 == i2)
return number.compareTo(o2.number);
else return i2 - i1;
}
private int numPart() {
int dashPos = number.indexOf('-');
String numPart = number.substring(1, 
dashPos == -1 ? number.length() : dashPos);
try {
if (numPart.length() > 0)
return Integer.parseInt(numPart);
} catch (NumberFormatException e) {
//
}
return 0;
}

@Override
public String toString() {
return number;
}
}

让我们测试一下:

class Test {
public static void main(String[] args) {
List<Obj> lstObjects = Arrays.asList(
new Obj("#3772-BOZ-007"),
new Obj("#3772-BAZ-02"),
new Obj("#31-002"),
new Obj("#001"),
new Obj("#19"),
new Obj("#22"),
new Obj("#21"),
new Obj("#6"));
lstObjects.sort(Comparator.naturalOrder());
lstObjects.forEach(System.out::println);
}
}

结果:

#001
#6
#19
#21
#22
#31-002
#3772-BAZ-02
#3772-BOZ-007

Object是java.lang已经使用的术语。对象,因此作为示例名称相当令人困惑。我假设你写了Obj来代替这个答案的其余部分。

sort方法采用比较器,比较列表中的元素。比较器是一个oracle,它返回任意两个对象,其中一个是"更早的"。

您的列表由您粘贴的Obj类的实例组成,它没有定义的自然顺序。

你有两个选择:

让这个类有一个自然的顺序

这样做,使类实现Comparable<Self>。因此:

public class Obj implements Comparable<Obj> {
private String number;
@Override public int compareTo(Obj other) {
return this.number.compareTo(other.number);
}
}
...
lstObjects.sort(Comparator.naturalOrder()):

提供对数值进行比较的比较器。

这假设你在Object类中有一个public String getNumber()方法:

lstObjects.sort(Comparator.comparing(Obj::getNumber));

可以实现Comparable接口,并在compareTo()方法中定义排序键和排序机制

的例子:

public class MyObject implements Comparable<MyObject> {
private String number;
public MyObject(String number) {
this.number = number;
}
@Override
public int compareTo(MyObject other) {
return this.number.compareTo(other.number);
}
}

让我们假设,你有一个class

package stack.overflow.atest;
public class Flight {
String number;
public Flight(String number) {
this.number = number;
}
@Override
public String toString() {
return "Flight{" + "number=" + number + '}';
}

}

代码段调用:

public static void main(String[] args) {
List<Flight> list = Stream.of(
"#3772-BOZ-007",
"#3772-BAZ-02",
"#31-002",
"#001"
).map(Flight::new)
.sorted((f1, f2) -> f1.number.compareTo(f2.number))
.collect(Collectors.toList());
System.out.println(list);
}

结果:

[Flight{number=#001}, Flight{number=#31-002}, Flight{number=#3772-BAZ-02}, Flight{number=#3772-BOZ-007}]

Objects进行排序
通过传递的ComparatorgroupingByHashMap-default更改为TreeMap来获得特定的排序顺序。
不要混淆Objectjava.lang.Object

static Pattern pat = Pattern.compile("(?:#(\d+))?(.*)?");
ArrayList<Object> list = new ArrayList<>();
Stream.of(
new Object("#3772-BOZ-007"),
new Object("#3772-BAZ-02"),
new Object("#31-002"),
new Object("#001"))
.collect(groupingBy(Object::getNumber,
() -> new TreeMap<String,List<Object>>(new Comparator<String>() {
@Override
public int compare(String num1, String num2) {
Matcher m1 = pat.matcher(num1);
Matcher m2 = pat.matcher(num2);
m1.find();
m2.find();
Integer i1 = m1.group(1) != null ? Integer.parseInt(m1.group(1)) : -1;
Integer i2 = m2.group(1) != null ? Integer.parseInt(m2.group(1)) : -1;
String s1 = m1.groupCount() > 1 ? m1.group(2) : "";
String s2 = m2.groupCount() > 1 ? m2.group(2) : "";
int cmp = i1.compareTo(i2);
return(cmp == 0 ? s1.compareTo(s2) : cmp);
}}), toList())).values()
.forEach(l -> list.addAll(l));
System.out.println(list);

Object#number排序:

[Object{number=#001},
Object{number=#31-002},
Object{number=#3772-BAZ-02},
Object{number=#3772-BOZ-007}]

相关内容

  • 没有找到相关文章

最新更新