如何从对象列表中的Java列表中获取最匹配的对象?

时间:2019-04-28 19:27:40

标签: java java-stream

我有一个用例,我需要根据对象参数从给定对象的列表中找到最匹配的对象

我在Java中有一个对象作为输入

例如

 TestBestMatchModel("VERIFICATION", "6", "13", "15");

有一个输入对象列表-

List<InputObject> list = new ArrayList<>();

其中包含一些对象:-

TestBestMatchModel testBestMatchModel = new TestBestMatchModel("VERIFICATION",
        "6", "99999", "999999");
    TestBestMatchModel testBestMatchModel1 = new TestBestMatchModel("VERIFICATION",
        "6", "13", "999999");
    TestBestMatchModel testBestMatchModel2 = new TestBestMatchModel("VERIFICATION",
        "6", "2", "999999");
    TestBestMatchModel testBestMatchModel3 = new TestBestMatchModel("VERIFICATION",
        "6", "213", "9");
    TestBestMatchModel testBestMatchModel4 = new TestBestMatchModel("VERIFICATION",
        "6", "113", "999999");
    TestBestMatchModel testBestMatchModel5 = new TestBestMatchModel("VERIFICATION",
        "6", "13", "9");

所以我正在使用像

这样的流方法
TestBestMatchModel result = test.stream()
            .filter(model -> model.getTransformation().equals("VERIFICATION")).max(
                Comparator.comparing(
                    model -> model.getLanguageID().equals("6")
                        && model.getVerticalID().equals("13")
                        && model.getDeviceID().equals("15")
                )).orElse(null);

我希望输出将是-testBestMatchModel5

但是相反,我在结果中得到“ testBestMatchModel”值

result is TestBestMatchModel{transformation='VERIFICATION', deviceID='999999', verticalID='99999', languageID='6'}

那么从对象列表中获取“最佳匹配”对象的最佳方法是什么。

2 个答案:

答案 0 :(得分:0)

您希望拥有“最佳匹配”逻辑,但您仅定义“匹配”逻辑就没有定义任何“最佳匹配”逻辑。
您只是在比较一个布尔值,该值表示“所有字段都相等”或不相等。

Comparator.comparing(
  model -> model.getLanguageID().equals("6")
         && model.getVerticalID().equals("13")
         && model.getDeviceID().equals("15")
)

尝试为您的班级定义Comparable,然后根据需要定义最佳匹配逻辑:

public class TestBestMatchModel implements Comparable<TestBestMatchModel> {

    @Override
    public int compareTo(TestBestMatchModel other) {
       // Define best match logic
       // For example for every field equals +1 in score
       int score = 0;
       if (this.getLanguageID().equals(other.getLanguageID())
         score++;
       if (this.getVerticalID().equals(other.getVerticalID())
         score++;
       if (this.getDeviceID().equals(other.getDeviceID())
         score++;

       return score;
    }
}

然后您可以使用它:

TestBestMatchModel searchFor =  TestBestMatchModel("VERIFICATION", "6", "13", "15");
TestBestMatchModel result = test.stream()
            .filter(model -> model.getTransformation().equals("VERIFICATION"))
            .max(Comparator.comparing(m -> searchFor.compareTo(m)))
            .orElse(null);

答案 1 :(得分:0)

首先,您会误解所编写的代码。首先了解max函数的实际作用。它将根据传递给它的键对对象进行排序,然后从中获取最大的收益。在您的情况下,列表中的所有对象都将false返回给max函数。现在,由于max函数中的每个键都是相同的,因此排序不会有任何效果(每个键都将是相同的(在这种情况下,FIFO将起作用)。)。在复杂对象之前,请尝试一些最大和最小函数here的基本程序。

model -> model.getLanguageID().equals("6")
                    && model.getVerticalID().equals("13")
                    && model.getDeviceID().equals("15")

由于side max函数中所有键的值相同,因此可以使用“先到先得”解决。因此,这与“ testBestMatchModel”无关, 如果您只是更改列表中的插入顺序,则会使用相同的代码给出不同的结果:请在下面的行中查看我的评论。
    list.add(testBestMatchModel1); //我将其放在testBestMatchModel之前;     list.add(testBestMatchModel); //我将此位置插入了第二个位置

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;

public class Test {
public static void main(String[] args) throws ParseException {

TestBestMatchModel testBestMatchModel1 = new 
TestBestMatchModel("VERIFICATION",
    "6", "13", "999999");
TestBestMatchModel testBestMatchModel = new TestBestMatchModel("VERIFICATION",
    "6", "99999", "999999");
TestBestMatchModel testBestMatchModel2 = new 
TestBestMatchModel("VERIFICATION",
    "6", "2", "999999");
TestBestMatchModel testBestMatchModel3 = new 
TestBestMatchModel("VERIFICATION",
    "6", "213", "9");
TestBestMatchModel testBestMatchModel4 = new 
TestBestMatchModel("VERIFICATION",
    "6", "113", "999999");
TestBestMatchModel testBestMatchModel5 = new 
TestBestMatchModel("VERIFICATION",
    "6", "13", "9");
List<TestBestMatchModel> list= new ArrayList<>();
list.add(testBestMatchModel1); // I put it before the testBestMatchModel;
list.add(testBestMatchModel); //I inserted this to second position
list.add(testBestMatchModel2);
list.add(testBestMatchModel3);
list.add(testBestMatchModel4);
list.add(testBestMatchModel5);

TestBestMatchModel test = new TestBestMatchModel("VERIFICATION", "6", "13", "15");
TestBestMatchModel result = list.stream()
    .filter(model -> model.getTransformation().equals("VERIFICATION"))
    .max(Comparator.comparing(
            model -> model.getX().equals("6")
                && model.getY().equals("13")
                && model.getZ().equals("15")
        ))
    .orElse(null);
System.out.println(result);

}
}

class TestBestMatchModel {

private String transformation;
private String x;
private String y;
private String z;

public TestBestMatchModel(String transformation, String x, String y, String z) 
{
this.transformation = transformation;
this.x = x;
this.y = y;
this.z = z;
}

public String getTransformation() {
return transformation;
}

public void setTransformation(String transformation) {
this.transformation = transformation;
}

public String getX() {
return x;
}

public void setX(String x) {
this.x = x;
}

public String getY() {
return y;
}

public void setY(String y) {
this.y = y;
}

public String getZ() {
return z;
}

public void setZ(String z) {
this.z = z;
}

@Override
public String toString() {
return "TestBestMatchModel{" + "transformation='" + transformation + '\'' + ", 
x='" + x + '\''
    + ", y='" + y + '\'' + ", z='" + z + '\'' + '}';
}

@Override
public boolean equals(Object o) {
if (this == o)
  return true;
if (o == null || getClass() != o.getClass())
  return false;
TestBestMatchModel that = (TestBestMatchModel) o;
return Objects.equals(transformation, that.transformation) && 
Objects.equals(x, that.x)
    && Objects.equals(y, that.y) && Objects.equals(z, that.z);
}

@Override
public int hashCode() {

return Objects.hash(transformation, x, y, z);
}
}