Reputation:
I have a model class Person
which implements the Comparable
interface and a compareTo(Personne o)
method which returns the proper int depending on the person's age.
Usecase: I want to check if all the persons inside the collection have the same age with an iterator
What I have so far:
while (collectionOfPerson.hasNext()) {
Person pers = collectionOfPerson.next();
if (pers.comparTo(collectionOfPerson.next()) == 0) {
}
}
Upvotes: 4
Views: 3045
Reputation: 25903
It is enough to grab only the first person and compare this to every other person, as you are testing if all have the same age.
Also, your comparison isn't correct, you have:
pers.comparTo(collectionOfPerson.next()) == 0
So you are trying to compare the current person to the next. But you have not tested if there is another person yet. So if you reached the end you will try to access a non existing person, yielding an error. You could easily fix that by comparing to the person of the last iteration. But, as said, you don't need that and could just compare to the first person every time.
Also, you should test for mismatch, not for matching ages.
Person first = collectionOfPerson.next();
while (collectionOfPerson.hasNext()) {
Person other = collectionOfPerson.next();
if (first.comparTo(other) != 0) {
// Found mismatch, abort
return false;
}
}
// Didn't found mismatch
return true;
Or a Stream
example that does not use Iterator
:
Person first = persons.iterator().next();
boolean allSameAge = persons.stream()
.allMatch(p -> p.compareTo(first) == 0);
An alternative using the enhanced for loop (for-each):
Person first = persons.iterator().next();
for (Person other : persons) {
if (other.compareTo(first) != 0) {
return false;
}
}
return true;
The following example filters all persons with the same age, only different ages remain. By that you can also easily collect the persons with other ages:
Person first = persons.iterator().next();
List<Person> otherAgePersons = persons.stream()
.filter(p -> p.compareTo(first) != 0)
.collect(Collectors.toList());
Upvotes: 3
Reputation: 717
I advocate for one solution using only streams.
Optional<Person> anyPerson = persons.stream().findAny();
boolean allSameAge = persons.stream()
.allMatch(p -> p.compareTo(anyPerson.get()) == 0);
I have to say that's not a semantic solution but it doesn't requires more work implementing new functions.
Following DDD to get a more semantic code you can change compareTo function for another which could be placed in Person class and have this contract:
public boolean hasSameAge(Person p);
Upvotes: 2
Reputation: 29710
Usecase: I want to check if all the persons inside the collection have the same age with an iterator
You can take advantage of streams along with an Iterator
if you'd like, assuming you a getAge
method within Person
and collectionOfPerson
is not empty:
if (!collectionOfPerson.hasNext()) {
return;
}
int age = collectionOfPerson.next().getAge();
collectionOfPerson.stream()
.mapToInt(Person::getAge)
.allMatch(i -> i == age);
If you're dead-set on solely using an Iterator<Person>
, then you were close! You can keep track of a boolean
and break out of the loop if any of the elements in the collection do not match the age of the first element:
if (!collectionOfPerson.hasNext()) {
return;
}
int age = collectionOfPerson.next().getAge();
boolean allMatch = true;
while (collectionOfPerson.hasNext()) {
if (collectionOfPerson.next().getAge() != age) {
allMatch = false;
break;
}
}
if (allMatch) {
// All of the ages are the same!
}
Upvotes: 3