Java List.Contains(Object with Field Value Equal to X)

Java List.contains(Object with field value equal to x)

Streams

If you are using Java 8, perhaps you could try something like this:

public boolean containsName(final List<MyObject> list, final String name){
return list.stream().filter(o -> o.getName().equals(name)).findFirst().isPresent();
}

Or alternatively, you could try something like this:

public boolean containsName(final List<MyObject> list, final String name){
return list.stream().map(MyObject::getName).filter(name::equals).findFirst().isPresent();
}

This method will return true if the List<MyObject> contains a MyObject with the name name. If you want to perform an operation on each of the MyObjects that getName().equals(name), then you could try something like this:

public void perform(final List<MyObject> list, final String name){
list.stream().filter(o -> o.getName().equals(name)).forEach(
o -> {
//...
}
);
}

Where o represents a MyObject instance.

Alternatively, as the comments suggest (Thanks MK10), you could use the Stream#anyMatch method:

public boolean containsName(final List<MyObject> list, final String name){
return list.stream().anyMatch(o -> name.equals(o.getName()));
}

Java List.contains(ArrayList String with field value equal to x)

You can simply use List.contains:

o -> o.getKeywordList().contains(keyword);

As a side note, your expression could be simplified with Stream.anyMatch:

public boolean containsKeyword(final List<KeywordPOJO> list, final String keyword){
return list.stream().anyMatch(o -> o.getKeywordList().contains(keyword));
}

Finding out if a list of Objects contains something with a specified field value?

I propose to create simple static method like you wrote, without any additional interfaces:

public static boolean containsId(List<DTO> list, long id) {
for (DTO object : list) {
if (object.getId() == id) {
return true;
}
}
return false;
}

How does a ArrayList's contains() method evaluate objects?

ArrayList implements the List Interface.

If you look at the Javadoc for List at the contains method you will see that it uses the equals() method to evaluate if two objects are the same.

Checking that a field in a List of Objects has a certain value?

You have to iterate over the List one way or another.

One convenient way to do it is with Java8 Streams :

boolean found = allPersons.stream().anyMatch(p->p.getAddress().equals(someAddress));

Java Stream over a list and check if the list contains at list one object with one of three given field values

Lets make it a fair fight, your original snippet is much, much longer than it needs to be:

boolean r = false, y = false, g = false;
for (Ball ball : balls) {
String color = ball.getColor();
if ("RED".equals(color)) r = true;
if ("YELLOW".equals(color)) y = true;
if ("GREEN".equals(color)) g = true;
if (r && y && g) return true;
}
return false;

Streams don't 'like it' if you have to refer to results of other operations. That's because the stream API tries to cater to way too many scenarios, thus, you get the lowest common denominator. Which, in this case, is parallel processing: Imagine java runs your stream by handing each individual item to a separated out system - now there is no longer such a thing as 'any previous result' or 'have we seen at least 1 red, at least 1 green, and at least 1 yellow ball at this point' - there is no 'this point', there's just the stream itself.

Hence, it's going to either look ugly (because you're using the wrong tool for the job), or, it's fundamentally far more inefficient. It would look something like this:

return balls.stream()
.map(Ball::getColor)
.filter(x -> x.equals("RED") || x.equals("GREEN") || x.equals("YELLOW"))
.distinct()
.count() == 3;

Comparing code lengths its not significantly simpler. It is considerably worse in performance: It needs to do a distinct scan which requires another run through, and must iterate the whole thing, whereas the first snippet will stop the moment it sees the third color.

Trying to smash those back in, you're looking at a real ugly mess. Golfed to as small as I could make it:

boolean[] c = new boolean[4];
return balls.stream()
.map(Ball::getColor)
.peek(x -> c[x.equals("RED") ? 0 : x.equals("YELLOW") ? 1 : x.equals("BLUE") ? 2 : 3] = true)
.anyMatch(x -> c[0] && c[1] && c[2]);

It's not much code but it introduces all sorts of weirdness - it's weird enough that this probably needs commentary to explain what's going on. So not really a 'win'. It certainly isn't going to be any faster than the original.

In general when you are iterating over a collection with the intent to contrast between values and those operations cannot be described in terms of primitives of the list itself (such as .distinct() or .sorted() or .limit) and there is no pre-baked terminal operation (such as .max()) that does what you want, it's rather likely you do not want streams.

Why does the 'contains' method return false when I enter the exact name on my ArrayList?

List.contains()uses Object.equals() to determine whether an Object is already in that List.

So one approach could be to overwrite that method:

public class Customer
{
private String m_Name;
private int m_Age;


@Override
public final boolean equals( final Object o )
{
return o instanceof String name && name.equals( m_Name );
}
}

Although this will work, it is not recommended to implement equals() in this way (see here as a starting point).

Instead you should search for the name in the list:

String name = scan.nextLine();
System.out.println( customers.stream().anyMatch( c -> c.getName().equals( name ) ) );

A completely different approach would be to store the Customer objects not in an instance of List but in an instance of Map, with the name as the key:

public class Main 
{
public static void main( String... args )
{
Scanner scan = new Scanner(System.in);
Map<String,Customer> customers = new HashMap<>();
var customer = new Customer( "Zen", 19, "0912121212", "zen@gmail.com" );
customers.put( customer.getName(), customer );
customer = new Customer( "Mary", 20, "09134343434", "mary@gmail.com" );
customers.put( customer.getName(), customer );
System.out.println( "Enter name: " );
String name = scan.nextLine();
System.out.println( customers.containsKey( name ) );
}
}

Finally, it would help in general if you would follow the basic naming conventions for the Java language: class names are starting with a Capital letter.



Related Topics



Leave a reply



Submit