Sort String Length, but reversed (longest String first)

51 views Asked by At

I have to do an excercise where i have to write a method orderQuestionsByLength(), which should sort questions by its length (descending)

the following code works (but it's not sorted descending):

`public void orderQuestionsByLength(){
        Collections.sort(questions,Comparator.comparing(question -> question.getText().length())); 
        for (Question question : questions){                                                       
            System.out.println(question);
        }
    }`

as soon as i add .reversed() my IDE throws an error Cannot resolve method 'getText' in 'Object' even though i have a method getText() and it worked before adding .reversed()

it drives me crazy, bc i don't know how to solve the problem, gpt says my code is right (not saying that i should rely on gpt, but i have another method where i sort integers descending, where i used reversed() without any problems

2

There are 2 answers

0
CHF On BEST ANSWER

This can sometimes happen because the Comparator.comparing method can't correctly infer the type of the lambda parameter when it's chained with .reversed().

To solve this issue, you can provide explicit type information in the lambda expression. Here's how you can modify your orderQuestionsByLength method with (String question) -> ….

public void orderQuestionsByLength() {
    Collections.sort(questions, Comparator.comparing((Question question) -> question.getText().length()).reversed()); 
    for (Question question : questions) {                                                       
        System.out.println(question);
    }
}
3
Basil Bourque On

Call Comparator#reversed.

Be careful in your syntax. Call reversed after producing the comparator with Comparator.comparing.

  • Comparator.comparing is a static method call, producing an instance (an object).
  • Comparator#reversed is an instance method call, producing another object.

As pointed out in Answer by CHF, you may need to be explicit with the data type of the argument passed to the lambda: ( String question ) -> ….

public void orderQuestionsByLength()
{
    Collections.sort( 
        questions, 
        Comparator
            .comparing( ( String question ) -> question.getText().length() )  // Static method call. 
            .reversed()  // Instance method call. 
    ); 
    questions.forEach( System.out :: println ) ;  
}

By the way, you can collapse that for loop by using Collections#forEach with a method reference, as seen above.


Full example app code:

package work.basil.example;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class Infer
{
    public static void main ( String[] args )
    {
        Comparator < Question > comparator =
                Comparator
                        .comparing ( ( Question question ) -> question.text ( ).length ( ) )
                        .reversed ( );

        ArrayList < Question > questions =
                new ArrayList <> (
                        List.of (
                                new Question ( "alpha" , 1 ) ,
                                new Question ( "b" , 2 ) ,
                                new Question ( "gamma" , 3 )
                        )
                );
        questions.sort ( comparator );
        questions.forEach ( System.out :: println );
    }
}

record Question( String text , int points ) { }