如何根据另一个列表中包含的属性对 Java 对象列表进行排序?

问题描述 投票:0回答:2

有什么方法可以根据另一个列表包含的属性对对象列表进行排序吗?

例如,我尝试按

ArrayList
customObjects
CustomObject
的值对
ArrayList
models
String
进行排序:

ArrayList<CustomObject> customObjects= new ArrayList<>();
customObjects.add(new CustomObject("Volvo", 1, "x1", 200, 4, 15000, true, 4));
customObjects.add(new CustomObject("Bmw", 2, "x2", 200, 4, 15000, true, 4));
customObjects.add(new CustomObject("Mercedes", 3, "x3", 200, 4, 15000, true, 4));
customObjects.add(new CustomObject("Alfa", 4, "x4", 200, 4, 15000, true, 4));
customObjects.add(new CustomObject("Fiat", 5, "x5", 200, 4, 15000, true, 4));

ArrayList<String> models = new ArrayList<>();
models.add("x2");
models.add("x5");
models.add("x1");
models.add("x4");
models.add("x3");

预期结果:

customObjects = [
  {CustomObject("Bmw", 2, "x2", 200, 4, 15000, true, 4))}
  {CustomObject("Fiat", 5, "x5", 200, 4, 15000, true, 4)}
  {CustomObject("Volvo", 1, "x1", 200, 4, 15000, true, 4)}
  {CustomObject("Alfa", 4, "x4", 200, 4, 15000, true, 4)}
  {CustomObject("Mercedes", 3, "x3", 200, 4, 15000, true, 4)}
]

请注意,列表大小可能不同。

java sorting arraylist java-stream comparator
2个回答
1
投票

使用模型的索引。我缩短了你的课程以使其更明显,但想法是一样的。

演示目的记录

record CustomObject(String car, int v1, String getSortId) {
}

数据

ArrayList<CustomObject> customObjects = new ArrayList<>();
customObjects.add(new CustomObject("Volvo", 1, "x1"));
customObjects.add(new CustomObject("Bmw", 2, "x2"));
customObjects.add(new CustomObject("Mercedes", 3, "x3"));
customObjects.add(new CustomObject("Alfa", 4, "x4"));
customObjects.add(new CustomObject("Fiat", 5, "x5"));

ArrayList<String> models = new ArrayList<>();
models.add("x2");
models.add("x5");
models.add("x1");
models.add("x4");
models.add("x3");

解决方案。使用 sortId,您可以对该 id 在模型中的相对位置进行排序。

customObjects.sort(Comparator
        .comparing(custObj -> models.indexOf(custObj.getSortId())));
customObjects.forEach(System.out::println);

打印

CustomObject[car=Bmw, v1=2, getSortId=x2]
CustomObject[car=Fiat, v1=5, getSortId=x5]
CustomObject[car=Volvo, v1=1, getSortId=x1]
CustomObject[car=Alfa, v1=4, getSortId=x4]
CustomObject[car=Mercedes, v1=3, getSortId=x3]

如果模型中不存在sortId,则返回-1,这样相似的对象将按升序排列在前面。


0
投票

您可以为此编写自己的比较器。我用 X 来称呼你的字符串为“xString”,就像这样

public class CustomObject {

    private final String volvo;
    private final int i;
    private final String xString;
    private final int i1;
    private final int i2;
    private final int i3;
    private final boolean b;
    private final int i4;

    public CustomObject(String volvo, int i, String type, int i1, int i2, int i3, boolean b, int i4) {
        this.volvo = volvo;
        this.i = i;
        this.xString = type;
        this.i1 = i1;
        this.i2 = i2;
        this.i3 = i3;
        this.b = b;
        this.i4 = i4;
    }

    public String getXString() {
        return xString;
    }

}

在您的代码中,您可以像这样比较模型列表的索引:

    @Test
    public void testSorting() {

        List<CustomObject> customObjects = new ArrayList<>();
        customObjects.add(new CustomObject("Volvo", 1, "x1", 200, 4, 15000, true, 4));
        customObjects.add(new CustomObject("Bmw", 2, "x2", 200, 4, 15000, true, 4));
        customObjects.add(new CustomObject("Mercedes", 3, "x3", 200, 4, 15000, true, 4));
        customObjects.add(new CustomObject("Alfa", 4, "x4", 200, 4, 15000, true, 4));
        customObjects.add(new CustomObject("Fiat", 5, "x5", 200, 4, 15000, true, 4));


        List<String> models = new ArrayList<>();
        models.add("x2");
        models.add("x5");
        models.add("x1");
        models.add("x4");
        models.add("x3");

        // Compator#compare returns int that tells which object is first and which second, see the Javadoc.
        // You can write your own comparator by just subtracting the indexes in the list.
        customObjects.sort((car1, car2) -> models.indexOf(car1.getXString()) - models.indexOf(car2.getXString()));

        System.out.println(customObjects);
    }

这不能处理特殊情况,例如在列表中找不到属性、空值等......,但您可以明白这个想法。

更短的排序方式,但对于不熟悉 lambda 的人来说不太容易理解,可以如下所示:

    customObjects.sort(Comparator.comparingInt(car -> models.indexOf(car.getXString())));
© www.soinside.com 2019 - 2024. All rights reserved.