Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

A interface Comparator tem mais de um método, por que consigo utilizar lambda?

Por definição apresentada na aula de lambda, vimos que a lambida só pode ser aplicada em uma interface funcional (que só possui um metodo abstrato).

Observe a notação utilizada :

palavras.sort(Comparator.comparing(s -> s.length()));

note que se acessarmos o método comparing, temos o seguinte:

  public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
            Function<? super T, ? extends U> keyExtractor)
    {
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
    }

Eu compreendo devemos passar por parâmetro as variáveis para o método Function( que é uma interface funcional), até aqui pra mim, faz sentido, entretanto até mesmo dentro de Function nós temos outros métodos, veja :

@FunctionalInterface public interface Function<T, R> {

/**
 * Applies this function to the given argument.
 *
 * @param t the function argument
 * @return the function result
 */
R apply(T t);

/**
 * Returns a composed function that first applies the {@code before}
 * function to its input, and then applies this function to the result.
 * If evaluation of either function throws an exception, it is relayed to
 * the caller of the composed function.
 *
 * @param <V> the type of input to the {@code before} function, and to the
 *           composed function
 * @param before the function to apply before this function is applied
 * @return a composed function that first applies the {@code before}
 * function and then applies this function
 * @throws NullPointerException if before is null
 *
 * @see #andThen(Function)
 */
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
    Objects.requireNonNull(before);
    return (V v) -> apply(before.apply(v));
}

/**
 * Returns a composed function that first applies this function to
 * its input, and then applies the {@code after} function to the result.
 * If evaluation of either function throws an exception, it is relayed to
 * the caller of the composed function.
 *
 * @param <V> the type of output of the {@code after} function, and of the
 *           composed function
 * @param after the function to apply after this function is applied
 * @return a composed function that first applies this function and then
 * applies the {@code after} function
 * @throws NullPointerException if after is null
 *
 * @see #compose(Function)
 */
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
    Objects.requireNonNull(after);
    return (T t) -> after.apply(apply(t));
}

/**
 * Returns a function that always returns its input argument.
 *
 * @param <T> the type of the input and output objects to the function
 * @return a function that always returns its input argument
 */
static <T> Function<T, T> identity() {
    return t -> t;
}

}

Minha dúvida é :

Para utilizar lambdas eu preciso que a minha interface contenha um Único método abstrato, ou seja um método que espera ser implementado quando eu coloco s -> s.length , eu estou passando esse parâmetro para qual método dentro de Function?

A interface Comparator também é definida como @functionalInterface, se eu for usar lambda no método que a classifica como tal, como ficaria?

No exemplo que coloquei por que não posso colocar :

palavras.sort(Comparator.comparing(String s -> s.length()));

Sendo que , Function, espera recebe um generics certo?

Function<T,R>Represents a function that accepts one argument and produces a result.

Só para deixar bem definido aqui pra mim:

Sempre que eu uso lambda, eu estou chamando um método sem corpo certo? nunca para um método com corpo, correto?

1 resposta
solução!

Sobre a questão: Para utilizar lambdas eu preciso que a minha interface contenha um Único método abstrato, ou seja um método que espera ser implementado quando eu coloco s -> s.length , eu estou passando esse parâmetro para qual método dentro de Function?

Resposta: O parâmetro é passado para o método apply(T). É verdade que existem outros métodos na interface Function, além do apply, porém todos possuem uma implementação default. Deste modo, apenas um único método é abstrato, que é o apply, o que torna a interface Function compatível com a notação lambda.

Sobre a questão: No exemplo que coloquei por que não posso colocar : palavras.sort(Comparator.comparing(String s -> s.length()));

Resposta: Porque pra poder declarar o tipo da variável usando lambda, é preciso colocar a declaração entre parênteses: palavras.sort(Comparator.comparing((String s) -> s.length()));

Sobre a questão: Sempre que eu uso lambda, eu estou chamando um método sem corpo certo? nunca para um método com corpo, correto?

Resposta: Pode-se dizer que sim. Você usa a notação lambda pra fornecer uma implementação pra uma interface funcional, que é uma interface que possui um único método abstrato. O código passado pelo lambda representa a implementação concreta desse único método abstrato da interface.