Search code examples
javagenericscollectionsgeneric-collections

Generic method arguments - Java


I have two almost identical methods, but I'm trying to avoid code duplication.

Each of them takes a unique object as arguments and finds out the highest value from it.

Here's an example:

public Integer getHighestIndexValue(List<ObjectA> list) {
    int highestValue;
    List<Integer> indexes = new ArrayList<Integer>();
    for (ObjectA a: list) {
        indexes.add(Integer.parseInt(a.getA()));
    }
    highestValue = Collections.max(indexes);

    return highestValue;

} 

Or:

public Integer getHighestIndexValue(List<ObjectB> list) {
    int highestValue;
    List<Integer> indexes = new ArrayList<Integer>();
    for (ObjectB b: list) {
        indexes.add(Integer.parseInt(b.getB()));
    }
    highestValue = Collections.max(indexes);

    return highestValue;

}  

How do I combine these two using generic parameters?

I tried creating a BaseClass that contains these two classes and extended it in the method signature. Still it requires casting.

public <T extends BaseClass> Integer getHighestIndexValue(List<T> objectList) {
    int highestValue;
    List<Integer> indexes = new ArrayList<Integer>();

    for (T objects: objectList) {
        indexes.add(Integer.parseInt(objects.getAorB())); ------ this line needs casting
    }
    highestValue = Collections.max(indexes);

    return highestValue;

}

I have used Generics before but not generics parameters yet.

Is there a way to resolve this?


Solution

  • Can getA and getB be combined into a single interface method?

    For example:

    interface ProvidesIndex {
      Integer getIndex();
    }
    

    Now, you can simply call getIndex, and your method signature will be:

    public Integer getHighestIndexValue(List<? extends ProvidesIndex> list) 
    

    As a side note, if you define your interface to extend Comparable<ProvidesIndex> i.e.:

    interface ProvidesIndex extends Comparable<ProvidesIndex>
    

    Then you can use Collections.max directly on the initial list:

    List<ProvidesIndex> list = new ArrayList<ProvidesIndex>();
    list.add(new ObjectA());
    list.add(new ObjectB());
    Integer max = Collections.max(list).getIndex();