• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
    • Questions
    • Teachers
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

269
Views
Comparator.comparing(...) lanza una excepción de referencia no estática mientras toma String::compareTo

A continuación se muestran las dos líneas de mi fragmento de código:

 List<String> listDevs = Arrays.asList("alvin", "Alchemist", "brutus", "larsen", "jason", "Kevin"); listDevs.sort(Comparator.comparing(String::length)); //This works fine listDevs.sort(String::compareToIgnoreCase); //This works fine

Pero (por experiencia) cuando trato de escribir

 listDevs.sort(Comparator.comparing(String::compareToIgnoreCase));

El compilador arroja error

No se puede hacer una referencia estática al método no estático compareToIgnoreCase(String) del tipo String

Similar sucede con el siguiente código

 listDevs.sort(Comparator.comparing(String::compareTo));

Entiendo el error y que funciona bien si elimino Comparator.comparing (como se muestra arriba).

Pero mi punto es, ¿cómo funciona esta línea?

listDevs.sort(Comparator.comparing(String::length));

Creo que me estoy perdiendo algo. He leído este hilo. ¿Es este el mismo escenario?

almost 3 years ago · Santiago Trujillo
3 answers
Answer question

0

Comparator.comparing espera una Function que describa una propiedad comparable de los elementos. Entonces String::length es suficiente ya que length() es una propiedad de String que evalúa una String a un int (por eso es preferible comparingInt aquí).

Por el contrario, String.compareToIgnoreCase y String.compareTo son métodos de comparación . Comparan dos objetos String . Por lo tanto, las referencias a ellos son suficientes donde se espera un Comparator , pero no donde se espera una Function de propiedad.

Es como si tuvieras una fábrica que dice: "Dame un motor y construimos un automóvil para ti" y estás tratando de darles un automóvil completo. Si bien ese automóvil existente es válido donde se espera un automóvil, no tiene sentido pasarlo a la fábrica para construir un automóvil.

Desafortunadamente, la implementación actual del compilador es muy mala para informar errores con firmas funcionales. Casi siempre verá mensajes como "No se puede hacer una referencia estática al método no estático..." cuando las firmas no coincidan.

almost 3 years ago · Santiago Trujillo Report

0

El método de sort esperaba un Comparator .

Cuando haces esto, de hecho estás proporcionando uno.

 listDevs.sort(Comparator.comparing(String::length));

Lo mismo sucede aquí (pero un poco no intuitivo):

 listDevs.sort(String::compareToIgnoreCase) listDevs.sort((left, right) -> left.compareToIgnoreCase(right)); // same thing as above

Esa es exactamente la definición de un Comparator : toma dos cadenas y devuelve un int.

La línea que dices cómo es que esto funciona: listDevs.sort(Comparator.comparing(String::length)); en realidad es bastante simple.

Comparator.comparing toma una Function que transforma su tipo de entrada en algo que es Comparable . En su caso, toma una String y devuelve un Integer ; que es comparable.

almost 3 years ago · Santiago Trujillo Report

0

JLS dice que la declaración de tiempo de compilación de una referencia de método de ReferenceType :: [TypeArguments] Identifier se puede interpretar de diferentes maneras.

Dado un tipo de función objetivo con n parámetros, se identifica un conjunto de métodos potencialmente aplicables:

ReferenceType :: [TypeArguments] El identificador tiene dos aridades diferentes, n y n-1, que se consideran para tener en cuenta la posibilidad de que esta forma se refiera a un método estático o a un método de instancia.

Una expresión de referencia de método de la forma ReferenceType :: [TypeArguments] Identifier se puede interpretar de diferentes maneras. Si Identifier hace referencia a un método de instancia, la expresión lambda implícita tiene un parámetro adicional con el tipo this en comparación con si Identifier hace referencia a un método estático. Es posible que ReferenceType tenga ambos tipos de métodos aplicables, por lo que el algoritmo de búsqueda descrito anteriormente los identifica por separado, ya que existen diferentes tipos de parámetros para cada caso.

Comparator.comparing method accept a Function<T,R extends Comparable<? súper R>> . cuando usa String::compareToIgnoreCase que informará un error, porque tiene dos parámetros, uno está implícito, este otro es una cadena de comparación del parámetro del método, por lo que es más como una BiFunction<String,String,Integer> no una Function<String,Integer> .

 BiFunction<String, String, Integer> comparator = String::compareToIgnoreCase; // you can't assign a BiFunction to a Function // because one is incompatiable with another. Function<String,Integer> function = comparator;

El método Stream.sort acepta un Comparator , y Comparator es más como un BiFunction<T,T,Integer> por lo que es compatible con String::compareToIgnoreCase . por otro lado, pueden ser intercambiables. por ejemplo:

 Comparator<String> primary = String::compareToIgnoreCase; BiFunction<String, String, Integer> comparator1 = primary::compare; Comparator<String> comparator2 = comparator1::apply;

puede usar comparing(String::toLowerCase) en su lugar, es igual a String::compareToIgnoreCase , por ejemplo:

 // String::compareToIgnoreCase listDevs.sort(String::compareToIgnoreCase); // comparing(String::toLowerCase) listDevs.sort(comparing(String::toLowerCase))
almost 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error