java: Arrays.sort() with lambda expression

95,613

Solution 1

The cleanest way would be:

Arrays.sort(months, Comparator.comparingInt(String::length));

or, with a static import:

Arrays.sort(months, comparingInt(String::length));

However, this would work too but is more verbose:

Arrays.sort(months,
            (String a, String b) -> a.length() - b.length());

Or shorter:

Arrays.sort(months, (a, b) -> a.length() - b.length());

Finally your last one:

Arrays.sort(months, 
    (String a, String b) -> { return Integer.signum(a.length() - b.length()) }; 
);

has the ; misplaced - it should be:

Arrays.sort(months, 
    (String a, String b) -> { return Integer.signum(a.length() - b.length()); }
);

Solution 2

You're looking for this:

Arrays.sort(months, (a, b) -> Integer.signum(a.length() - b.length()));

Solution 3

The functionality you are looking for is in Java 8, which has not yet been released. It is scheduled for release in a few months if you want to wait, or if not beta downloads are available.

Share:
95,613
matt-pielat
Author by

matt-pielat

Updated on October 29, 2020

Comments

  • matt-pielat
    matt-pielat over 3 years

    I want to sort String elements in the array months by length using Arrays.sort method. I was told here, that it's possible to use lambda expressions instead of creating new class implementing Comparator. Did it exactly the same way, yet it doesn't work.

    import java.util.Arrays;
    import java.util.Comparator;
    
    public class MainClass {
    public static void main(String[] args)
    {
    
        String[] months = {"January","February","March","April","May","June","July","August","September","October","December"};
    
        System.out.println(Arrays.toString(months)); //printing before
    
    
        //neither this works:
        Arrays.sort(months, 
                (a, b) -> Integer.signum(a.length() - b.length())   
        );
    
        //nor this:
        Arrays.sort(months, 
                (String a, String b) -> { return Integer.signum(a.length() - b.length()) }; 
        );
    
    
        System.out.println(Arrays.toString(months)); //printing after
    }
    }
    
  • skiwi
    skiwi about 10 years
    +1 for showing Comparator.comparing, it is so much easier to grasp than writing a custom lambda or Comparator.
  • matt-pielat
    matt-pielat about 10 years
    Well, that's helpful, but I'd like to know what's wrong with my solution.
  • Josh M
    Josh M about 10 years
    Works for me... Are you sure you're using Java 8? Which IDE are you using?
  • assylias
    assylias about 10 years
    @lavsprat I have added something showing your syntax error.
  • skiwi
    skiwi about 10 years
    @lavsprat It also works for me, it prints [May, June, July, March, April, August, January, October, February, December, September]... What Java 8 version are you using?
  • Vishy
    Vishy about 10 years
    I suggest using Integer.compare instead of signum of -.
  • assylias
    assylias about 10 years
    @PeterLawrey Indeed - signum(a-b) has the risk of overflowing (even if it's unlikely for strings).
  • assylias
    assylias about 10 years
    @lavsprat Then you don't have java 8 installed or you are not compiling with the right JDK or your IDE does not support it or you have a very old version or...
  • matt-pielat
    matt-pielat about 10 years
    I'm using Eclipse. This site says I have Version 7 Update 51.
  • matt-pielat
    matt-pielat about 10 years
    Oracle site says "You have the recommended Java installed (Version 7 Update 51).".
  • assylias
    assylias about 10 years
    @lavsprat huh.... Version 7 != Version 8... Java 8 is here: jdk8.java.net/download.html
  • Josh M
    Josh M about 10 years
    Well of course you can't use lambdas then, as they are only available in Java 8.
  • Stuart Marks
    Stuart Marks about 10 years
    I don't think - can overflow in this case, as both values are non-negative.
  • Ted Hopp
    Ted Hopp about 10 years
    Useful comment, but not an answer.
  • Tim B
    Tim B about 10 years
    @TedHopp It is an answer. His code isn't compiling because he's trying to use a Java 8 feature in Java 7!
  • Ted Hopp
    Ted Hopp about 10 years
    His code isn't compiling because it has a syntax error (semicolon at the end of the second argument to Arrays.sort).
  • Holger
    Holger about 10 years
    Integer.signum is obsolete. Just returning a-b (for these special a and b where a-b cannot overflow, of course) is enough. There is no need to set the absolute value to 1. So wrapping a value which has the right sign already with an Integer.signum(…) call makes no sense for a Comparator.
  • Maurice Naftalin
    Maurice Naftalin about 10 years
    This comment is a bit misleading, unless you count three weeks as being "a few months": ship date is March 18th
  • Ole V.V.
    Ole V.V. over 7 years
    I certainly prefer Comparator.comparingInt() over comparing() when what you are comparing are indeed ints. It’s clearer (and also avoids unnecessary boxing).