Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
186 views
in Technique[技术] by (71.8m points)

java - Comparing two objects for varying set of properties

I have a data class. Fields can be collections, primitives, references etc. I have to check the equality of two instances of this class. Generally we override equals method for this purpose. But usecase is such that properties which are to be compared may vary.

So say, class A has properties:

int name:
int age:
List<String> hobbies;

In one invocation I may have to check equality based on name,age, and for another invocation I may have to check equality for name, hobbies.

What is best practice to achieve this?

question from:https://stackoverflow.com/questions/66047276/comparing-two-objects-for-varying-set-of-properties

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

anyMatch

You can solve this with the Stream API, using anyMatch, with your rules basically being defined as Predicates.

For example checking if there is any person who is 20 years old:

List<Person> persons = ...

boolean doesAnyMatch = persons.stream()
    .anyMatch(p -> p.getAge() == 20);

You can of course also setup the rule in a way that it compares with an existing item, mimicking equals a bit more:

p -> p.getAge() == otherPerson.getAge()

Predicate

You can setup all your rules somewhere else, as Predicates and then use them. For example:

List<Predicate<Person>> rules = List.of(
    p -> p.getAge() == 20,
    p -> p.getName().equals("John"),
    p -> p.getAge() > 18,
    p -> p.getName().length() > 10 && p.getAge() < 50
);

And then maybe use them in some sort of loop, whatever you need:

for (Predicate rule : rules) {
    boolean doesAnyMatch = persons.stream()
        .anyMatch(rule);
    ...
}

findAny

You can substitute anyMatch by a combination of filter and findAny to receive an actual match, i.e. a Person, instead of just a boolean:

Person matchingPerson = persons.stream()
    .filter(rule)
    .findAny();

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...