Home > Software design >  Select max from a List using Generics
Select max from a List using Generics

Time:01-03

I have to write a method which selects the maximum value from a list, and it has to be with Generics. Obviously the List can be Number and String as well. (The return value has to be Opt Object. This is the tasks.)

This is what I have so far, but its not working, I would appreciate your advice:

public static <T> Opt<T> max(List<? extends Object> list) {
    T max = (T) list;
    for (int i = 0; i < list.size(); i  ) {
        if (list.get(i) > max) {
            max = (T) list.get(i);
        }
    }
    return (Opt<T>) max;
}

And this is the main looks like: (From this one I have to make my method work.)

public static void main(String[] args) { 
   
List<String> stringList = new ArrayList<>();
    Utility.addTo(stringList, "aghi");
    Utility.addTo(stringList, "fed");
    Utility.addTo(stringList, "ghh");
    Utility.addTo(stringList, "abc");
    Utility.addTo(stringList, "123");
    System.out.println("The maximum value: "   Utility.max(stringList).get());

List<Integer> intList = new ArrayList<>();
    Utility.addTo(intList, 123);
    Utility.addTo(intList, 456);
    Utility.addTo(intList, -199);
    Utility.addTo(intList, -90);
    Utility.addTo(intList, 0);
    Utility.addTo(intList, -10);
    Utility.addTo(intList, 200);
    System.out.println("The maximum value: "   Utility.max(intList).get());

List<Double> doubleList = new ArrayList<>();
    Utility.addTo(doubleList, 123.0);
    Utility.addTo(doubleList, 456.001);
    Utility.addTo(doubleList, -199.0);
    Utility.addTo(doubleList, -90.90);
    Utility.addTo(doubleList, 0.0);
    Utility.addTo(doubleList, -10.20);
    Utility.addTo(doubleList, 200.1);
    System.out.println("The maximum value: "   Utility.max(doubleList).get());
}

And the Output shoud be:

The maximum value: ghh
The maximum value: 456
The maximum value: 456.001

CodePudding user response:

Your code is not working (I mean cannot be compiled) because of this line:

if (list.get(i) > max) {

In Java, there are no overloaded operators as in C , so you need to find another way...

By Opt you probably meant java.util.Optional class and you can use it like this:

    public static <T> Optional<T> max(List<T> list) {
        Optional<T> max = Optional.empty();
        for (int i = 0; i < list.size(); i  ) {
//            if (list.get(i) > max) {
                max = Optional.of(list.get(i));
//            }
        }
        return max;
    }

This is of course not working, it returns last element from list.

When creator of a class expects users might be interested in sorting (comparing), they would implemente java.lang.Comparable, this is the case for String, Long and Double. So instead of T, you can say T extends Comparable like this:

    public static <T extends Comparable<T>> Optional<T> max(List<T> list) {
        T max = null;
        for (int i = 0; i < list.size(); i  ) {
            final T item = list.get(i);
            if (max == null) {
                max = item;
            } else if (max.compareTo(item) < 0) {
                max = item;
            }
        }
        if (max == null) return Optional.empty();
        return Optional.of(max);
    }

Look at Comparable#compareTo JavaDoc.

Try to understand what this line means exactly (and why you cannot use it with list of java.lang.Objects):

public static <T extends Comparable<T>> Optional<T> max(List<T> list) {

and why we do not need it in addTo:

public static <T> void addTo(List<T> list, T e) {

CodePudding user response:

Using Streams makes it really easy by doing all the work for you:

public static <T extends Comparable<T>> Optional<T> max(List<T> list) {
    return list.stream().max(Comparator.naturalOrder());
}

or the Collections class of utility functions:

public static <T extends Comparable<T>> Optional<T> max(List<T> list) {
    if (list.isEmpty()) {
        return Optional.empty();
    } else {
        return Optional.of(Collections.max(list, Comparator.naturalOrder()));
    }
}
  • Related