Get highest values

Discussion in 'Spigot Plugin Development' started by MaTaMoR_, Jun 23, 2016.

  1. Hi i was trying to get the highest values from a map using a comparator, and it's working fine and i have no problems with it, but somehow i feel like im doing it wrong, so i wanted to know if there's a better way to do this, right know im it doing it with this code :
    Code (Java):

    public class Top {
       
        private Top() {
           
        }

        public static <T extends Comparable> Collection<T> top(Collection<T> values) {
            List<T> top = new ArrayList<>();

            List<T> sorted = new ArrayList<>(values);
            Collections.sort(sorted);
            Collections.reverse(sorted);

            T highest = null;
            for(T value : sorted) {
                if(highest == null) {
                    highest = value;
                }

                if(value.compareTo(highest) == 0) {
                    top.add(value);
                }
            }
           
            return top;
        }
    }
     
     
    #1 MaTaMoR_, Jun 23, 2016
    Last edited: Jun 23, 2016
  2. Wait... you made an entire object just to get the highest value in a collection? o_O

    Just make a static util method that does the same thing the object does to get the highest but instead of it being an object it just returns the highest one and that's it
     
    • Agree Agree x 1
  3. you're sorting a Map? you could just use something like the top answer in this. i can't vouch for the speed, so you might have to benchmark on your own to see what you like more

    can't say there's anything wrong with it, might be a bit slower since he's sorting it and then reversing it
     
  4. I could do that too, i just did it and i didn't think about it, and i don't want the highest VALUE i want the highest VALUES.
     
  5. I remember using a NavigableMap mapping an int (the chance) to an object of your choice, then you can use NavigableMap#ceilingEntry() with a random int to get the value
     
    • Informative Informative x 1
  6. That will only return on entry, i want the highest VALUES not the highest VALUE, i might be explaining it wrong.
     
  7. I remember using an anonymous comparator in a project where I needed the top 5 key/value pairs in a Map, but I abandoned it long ago and don't have the source code on any of my computers. Sry!
     
  8. Then use a legacy for loop (for(int i = 0...) {)
     
  9. IK i can do that, i just want to know if there's a better way to do it.
     
  10. I agree with Billy, a TreeMap would make your job a whole lot easier than using a custom comparator. Just use it :p
     
  11. Using the TreeMap will do basically this :
    Code (Java):

            List<T> sorted = new ArrayList<>(values);
            Collections.sort(sorted);
     
    The rest of the code is to only get the highest VALUES.
    Lets say the List contains (3, 2, 1, 3) i only want (3, 3) not (2 or 1), if i only sort it, it would be something like this (1, 2, 3, 3).
     
  12. This is why you're iterating over it to get the highest values.
     
  13. Collections.reverse();

    Turns 1 2 3 to. 3 2 1
     
  14. And this is why im asking if there's a better way to it. I just want to know if there's a better way to do it. And im not talking about the short part.
     
  15. There isn't a method that I know of that will trim off the lowest values for you. Just iterate over it.
     
  16. I know exactly what you want. Stop barking at people and research ;)

    https://docs.oracle.com/javase/7/docs/api/java/util/TreeMap.html#subMap(K, K)
     
  17. Wait a minute... so all you want is the values? You dont care about the associated keys?

    In that case just do this:
    Code (Text):

    List<Integer> list = new ArrayList<Integer>(map.values());
    Collections.sort(list, Collections.reverseOrder());
    List<Integer> top3 = list.subList(0, 3);