25

I'm trying to sort a simple list of objects by a long - the below isn't working because one of the long strings is pushed to the top simply because it starts with a lower number. So I'm looking for a way to sort these by the actual long values directly

The current obj implementation looks something like the below. In the class I'm using this I call Collections.sort(trees);

public class Tree implements Comparable<Tree> {
    public String dist; //value is actually Long

    public int compareTo(Tree o) {
        return this.dist.compareTo(o.dist);
    }
}
Toran Billups
  • 27,111
  • 40
  • 155
  • 268
  • Why don't you just compare the long-values of `dist` in your compareTo(Tree o) method? – Jacob May 30 '11 at 12:05
  • 1
    Strings are compared alphabetically (not really but it's a good way to think of). Hence, 12 > 111. If you need to compare numbers use numbers, i.e. add one more field long. Or in the worst case compare the result of Long.parseLong(dist) – bestsss May 30 '11 at 12:05
  • Turns out I was actually comparing a double the entire time - sorry guys (went with Double.compare as my actual solution) awarded what I felt was a great answer to the Long problem though - flag it for removal if nothing else – Toran Billups May 30 '11 at 12:43
  • Use 'Long.compare(long x, long y)', see answer below – Robb Hoff Oct 20 '14 at 07:48

6 Answers6

49

Long.compare( x , y )

If you have an object that you want to sort on a long value, and it implements Comparable, in Java 7+ you can use Long.compare(long x, long y) (which returns an int)

E.g.

public class MyObject implements Comparable<MyObject>
{
  public long id;

  @Override
  public int compareTo(MyObject obj) {
    return Long.compare(this.id, obj.id);
  }
}

Call Collections.sort(my_objects) where my_objects is something like

  List<MyObject> my_objects = new ArrayList<MyObject>();
  // + some code to populate your list
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Robb Hoff
  • 1,719
  • 2
  • 17
  • 32
21

why not actually store a long in there:

public class Tree implements Comparable<Tree> {
    public long dist; //value is actually Long

    public int compareTo(Tree o) {
        return this.dist < o.dist ? -1 :
            this.dist > o.dist ? 1 : 0;
    }
}

that or first compare the length of the strings and then compare them

public String dist; //value is actually Long

public int compareTo(Tree o) {
    if (this.dist.length() != o.dist.length())
      return this.dist.length() < o.dist.length() ? -1 : 1;//assume the shorter string is a smaller value
    else return this.dist.compareTo(o.dist);
}
Positive Navid
  • 2,481
  • 2
  • 27
  • 41
ratchet freak
  • 47,288
  • 5
  • 68
  • 106
13

well if the dist variable is actually long then you might try using

public int compareTo(Tree o) {
    return Long.valueOf(this.dist).compareTo(Long.valueOf(o.dist));
}
Kendrick
  • 3,747
  • 1
  • 23
  • 41
cipher
  • 169
  • 3
5

Just an example I made for sorting Files by date using a Long comparator:

public File[] getAllFoldersByDescendingDate(File folder) {
    if (!folder.isDirectory()) {
        return null;
    }
    allFiles = folder.listFiles();
    Arrays.sort(allFiles, new Comparator<File>()
    {
        public int compare(final File o1, final File o2)
        {
            return Long.compare(o2.lastModified(), o1.lastModified());
        }
    });
    return allFiles;
}
djangofan
  • 28,471
  • 61
  • 196
  • 289
3

It depends on how you want to do things? Do you want to keep the current implementation of Comparable? If yes, use the sort method which takes a Comparator and implement a custom comparator which uses the actual "long" values of the string (Long.parseLong(dist)). If no, then just modify the current compareTo and use the Long values of the "dist".

BTW, I'd revisit the logic and ask myself why "dist" is of type String when it is actually a Long?

Sanjay T. Sharma
  • 22,857
  • 4
  • 59
  • 71
1

Why not

public class Tree implements Comparable<Tree> {
    public Long dist;

    public int compareTo(Tree o) {
        return this.dist.compareTo(o.dist);
    }
}
astay13
  • 6,857
  • 10
  • 41
  • 56
  • If performance can be an issue, it's better to use primitive. Otherwise, it seems that someone pointed out: "The emperor is naked!" :) – Positive Navid Aug 09 '23 at 08:49