Searching for a specific object in an ArrayList Is this an efficient way to search for a specific object in an ArrayList?

Product is the superclasS. Mobo, CPU, RAM, GPU... are the subclasses.
ArrayList(called stock) stores Product objects. I consider that they key i am searching is found when class and the attribute "model"(you can see the getter of the attribute in my code) are matching.

public static boolean checkAvailability(ArrayList&lt;Product&gt; stock, Product product) {
    boolean found = false;
    for(Product p: stock) {
        if(p instanceof Mobo &amp;&amp; (product.getModel() == p.getModel())) {
            found = true;
            break;
        };
        if(p instanceof CPU &amp;&amp; (product.getModel() == p.getModel())) {
            found = true;
            break;
        };
        if(p instanceof GPU &amp;&amp; (product.getModel() == p.getModel())) {
            found = true;
            break;
        };
        if(p instanceof RAM &amp;&amp; (product.getModel() == p.getModel())) {
            found = true;
            break;
        };
        if(p instanceof Monitor &amp;&amp; (product.getModel() == p.getModel())) {
            found = true;
            break;
        };
        if(p instanceof Keyboard &amp;&amp; (product.getModel() == p.getModel())) {
            found = true;
            break;
        };
        if(p instanceof Mouse &amp;&amp; (product.getModel() == p.getModel())) {
            found = true;
            break;
        };
        if(p instanceof Printer &amp;&amp; (product.getModel() == p.getModel())) {
            found = true;
            break;
        };
    };
    return found;
}
Your code is very wet (the opposite of DRY). It repeats a lot. Let's start with what you're trying to achieve:


You have an ArrayList of Products.
You want checkAvailability to return true if any Product within the given ArrayList has the same model and type of the given Product.


The way you've implemented this, with instanceof checks, is IMO not ideal. Instead, let's modify the Product class to have a custom equals() method to compare equality of Products; we can store the equality logic inside of the Product class so it's reusable.

The equals() method on an Object, by default, will act similar to == - that is, it will compare referential equality, but it's a common idiom to override this method to compare logical equality instead.

class Product {
    ...

    @Override()
    public boolean equals(Object other) {
        // This is unavoidable, since equals() must accept an Object and not something more derived
        if (other instanceof Product) {
            // Note that I use equals() here too, otherwise, again, we will check for referential equality.
            // Using equals() here allows the Model class to implement it's own version of equality, rather than
            // us always checking for referential equality.
            Product otherProduct = (Product) other;
            return otherProduct.getModel().equals(this.getModel());
        }

        return false;
    } 
}


Of course, this does lose the instanceof checking in your checkAvailability method, but you can easily reintroduce something similar by overriding equals() in the subclasses of Product if you wanted to reintroduce this check (Spoiler: You probably don't! Don't compare types unless you have to). At the very least, try to move equality logic to an equals() method on a class rather than comparing equality outside of the class. Encapsulation and reusability is always nice!

With this override, we can simplify checkAvailability to the following:

public static boolean checkAvailability(ArrayList&lt;Product&gt; stock, Product product) {
    for (Product p : stock) {
        if (p.equals(product)) {
            return true;
        }
    }

    return false;
}


Which can be simplified to use Java streams if you'd like.

public static boolean checkAvailability(ArrayList&lt;Product&gt; stock, Product product) {
    return stock.stream()
                .anyMatch(p -&gt; p.equals(product));
}


Or, even better, we can make the required type less specific:

public static boolean checkAvailability(Collection&lt;Product&gt; stock, Product product) {
    return stock.stream()
                .anyMatch(p -&gt; p.equals(product));
}


As an aside: it is generally good practice to reimplement hashCode() if you reimplement equals(). Without having more knowledge of your solution, it's difficult for me to tell you how to do this, but I would recommend you do it if you end up using my suggestions.

Another side note: If you find yourself making lots of comprehensions like this, I would recommend having checkAvailability accept a Stream&lt;Product&gt; instead of Collection&lt;Product&gt; so as to avoid creating multiple streams.