Home > Enterprise >  Find an object in a list without iterating it
Find an object in a list without iterating it

Time:05-17

I have a class with 3 properties:

private static class OrderListItem {
    public int price;
    public int size;
    public Type type;
}

Items of this class are added in a list. List<OrderListItem> orders_book = new ArrayList<>();

I want to find an object in a list with a specified price. But size and type do not matter. Can I do something like this:

int index = orders_book.indexOf(new OrderListItem(price, **any size**, **any type**)); ?

Or I just must do a "loop" search?

CodePudding user response:

If you need to retrieve an instance with a desired price, then you could use a collection stream with the filter and findAny operations.

int myPrice = /* any value you want */

//This will retrieve an instance with the disired price or null if none is found
OrderListItem item = orders_book.stream()
        .filter(i -> i.getPrice() == myPrice)
        .findFirst()
        .orElse(null);

Alternatively, if you want to retrieve the index of the object with the desired price, then you have two options:

  1. Redefine the equals method of your OrderListItem class, to equal two OrderListItems by their price, since the documentation of the indexOf method retrieves an element by its equals method. However, I wouldn't lean towards this solution, as in my opinion the sole price is not enough to equal two order items, but you definitely know better than me the kind of problem you're modelling. So, I'll leave the choice to you. Furthermore, if you redefine the equals method you should also redefine the hashCode method as the general hashcode contract states.

https://docs.oracle.com/javase/8/docs/api/java/util/List.html#indexOf-java.lang.Object-

Returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element. More formally, returns the lowest index i such that (o==null ? get(i)==null : o.equals(get(i))), or -1 if there is no such index.

class OrderListItem {
    public int price;
    public int size;
    public Type type;

    /* ... your implementation ...*/

    @Override
    public int hashCode() {
        return Objects.hash(price);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) return false;
        if (this == obj) return true;
        if (getClass() != obj.getClass()) return false;
        OrderListItem other = (OrderListItem) obj;
        return Objects.equals(price, other.price);
    }
}
  1. Not redefining the equals method, but retrieving the exact instance with a stream (like in the first snippet) and then using that same instance as a parameter for the indexOf invocation.
int myPrice = /* any value you want */

//This will retrieve an instance with the disired price or null if none is found
OrderListItem item = orders_book.stream()
        .filter(i -> i.getPrice() == myPrice)
        .findFirst()
        .orElse(null);

//Retrieving the index
int index = orders_book.indexOf(item);
  • Related