10

I needed a method to get the median of 3 values, I thought it a good opportunity to write a generic method since I don't really have that practiced. I wrote this and it seems pretty straight-forward, though I get a warning, but it seems to work fine, according to my tests.

I'm aware I could use an inherently sorted set, or Collections.sort(), but this approach is for the sake of understanding.

I want to pinpoint a few things:

  1. I noticed this doesn't work if I tried to declare medianHelper with Arrays.asList(a, b, c) why is this? Trying to search this gives me unrelated results and it's otherwise elusive since I'm not sure what is happening. I get an UnsupportedOperationException, but this is not present the way I have it below.
  2. Why am I getting a warning? What is wrong/missing?

The method follows:

private static <T extends Comparable> T median(T a, T b, T c) {
    List<T> medianHelper = new ArrayList<>();
    T max;
    T min;

    medianHelper.add(a);
    medianHelper.add(b);
    medianHelper.add(c);

    if (a.compareTo(b) >= 0) {
        max = a;
        min = b;
    } else {
        max = b;
        min = a;
    }

    if (max.compareTo(c) == -1) {
        max = c;
    }

    if (min.compareTo(c) >= 0) {
        min = c;
    }

    medianHelper.remove(max);
    medianHelper.remove(min);

    return medianHelper.get(0);
}
Legato
  • 578
  • 11
  • 21

1 Answers1

12

You haven't correctly introduced the type-parameter T, as Comparable is generic, too.

It should rather be:

private static <T extends Comparable<? super T>> T median(T a, T b, T c) 

Furthermore, you can just sort the medianHelper list, since its elements will be Comparable. So your method can be significantly shortened to:

private static <T extends Comparable<? super T>> T median(T a, T b, T c) {
    List<T> medianHelper = Arrays.asList(a, b, c);

    Collections.sort(medianHelper);

    return medianHelper.get(1);
}

Note that Arrays.asList() returns an unmodifiable list, which means you're not allowed to add/remove elements after it's created. If you wish to do the comparisons yourself, you can use new ArrayList<> instead of Arrays.asList() and then manually add the elements to it.

Konstantin Yovkov
  • 59,030
  • 8
  • 92
  • 140
  • 2
    That should even be `T extends Comparable super T>` – fge Apr 29 '15 at 08:39
  • Thank you, kocko. I completely overlooked that `Comparable` is generic, and thank you, fge for the important distinction that it also have an upper bound. I'm still perplexed on the topic of Arrays.asList errors if I want to do the comparisons myself. Any thoughts? – Legato Apr 29 '15 at 08:54
  • 2
    `Arrays.asList` returns an unmodifiable list, which means you can add/remove objects from it. I guess that's the error you're receiving now. :) If you wish to do the comparisons yourself, you can use `new ArrayList<>` and then manually add the elements to it. – Konstantin Yovkov Apr 29 '15 at 08:55
  • Thanks again, I think you should add that to your answer. – Legato Apr 29 '15 at 09:00