Как получить наиболее подходящий объект из списка в Java из списка объектов? - PullRequest
1 голос
/ 28 апреля 2019

У меня есть случай использования, когда мне нужно найти объект с наилучшим соответствием из списка данного объекта на основе параметров объекта

У меня есть объект в качестве Входных данных в 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 голосов
/ 28 апреля 2019

Прежде всего вы неверно истолковали код, который вы написали.Сначала поймите, как максимальная функция на самом деле.Он отсортирует ваш объект на основе переданных ему ключей, а затем вытащит из него максимум.В вашем случае все объекты в списке с возвращением false функции max.Теперь, поскольку каждая клавиша одинакова в max, сортировка функций не будет иметь никакого эффекта (каждая клавиша будет одинаковой (FIFO будет работать в этом случае.)).Перед сложным объектом попробуйте какую-нибудь базовую программу с функциями max и min здесь .

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

Поскольку все ключи имеют одинаковые значения в функции max стороны, она разрешается с помощью First First First First.Так что речь идет не о «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);
}
}
0 голосов
/ 28 апреля 2019

Вы хотите иметь "наилучшее совпадение", но вы не определяете какую-либо логику "наилучшего совпадения", только логику "сопоставления".
Вы просто сравниваете логическое значение, которое говорит "все поля равны" илине.

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...