A primeira vez que fui exposto a expressões Lambda foi no TypeScript (o superconjunto do JavaScript), e foi para tornar o método do datilografado fora desse método e não nesse método. Depois de usá -lo, de repente percebi que o Lambda não é um novo recurso do JDK8? Então, senti que verifiquei as informações relevantes e as gravei:
1. Parametrização de comportamento
Em resumo, a parametrização de comportamento significa que o corpo da função contém apenas código geral semelhante ao modelo, enquanto alguma lógica que muda com o cenário de negócios é transmitida para a função na forma de parâmetros. O uso da parametrização de comportamento pode tornar o programa mais geral para lidar com as necessidades de alterações frequentes.
Considere um cenário de negócios, assumindo que precisamos filtrar a Apple através de um programa, primeiro definimos uma entidade da Apple:
public class Apple {/** Número*/Private longo id;/** cor*/cor privada cor;/** peso*/peso de flutuação privada;/** origem*/origem de sequência privada; public Apple () {} public Apple (longa id, cor de cor, float, origem da string) {this.id = iD; this.color = cor; this.wust = weight = weight;A demanda inicial dos usuários pode ser simplesmente filtrar as maçãs verdes através do programa, para que possamos implementá -los rapidamente através do programa:
Lista estática pública <pple> filterGreenApples (list <pple> maçãs) {list <pple> filterapples = new ArrayList <> (); para (Final Apple Apple: Apples) {if (color.green.equals (Apple.getColor ())) {filterApples.add (Apple);}}} filtropples;}Este código é simples e nada que valha a pena dizer. Mas quando o usuário precisa ser verde, parece que a modificação do código é simples, nada mais do que alterar o verde da condição de julgamento para vermelho. Mas precisamos considerar outro problema. Se as condições de mudança mudarem com frequência, isso será feito? Se for apenas uma mudança de cor, podemos deixar o usuário passar nas condições de julgamento de cores e os parâmetros do método de julgamento alteram "o conjunto a ser julgado e a cor a ser filtrada". Mas e se o usuário não apenas julgar a cor, mas também quiser julgar peso, tamanho, etc.? Você acha que podemos apenas adicionar parâmetros diferentes para concluir o julgamento? Mas é realmente bom passar parâmetros como este? Se houver mais e mais condições de filtragem e o modo de combinação se tornar cada vez mais complexo, precisamos considerar todas as situações e ter estratégias de enfrentamento correspondentes para cada situação? Neste momento, podemos parametrizar o comportamento, extrair as condições de filtragem e passá -las como parâmetros. Neste momento, podemos encapsular uma interface de julgamento:
interface pública AppleFilter {/*** FILTRO DE RESUMO ** @PARAM Apple* @Return*/boolean Acep (Apple Apple);}/*** Encapsular filtros na interface ** @param Apples*@param filtro* @return*/public static list <ppleppleApplesbyapplefilter (list <pplepples> Applefilter) {listar filterapplesbyappleApplefilter (list <pple> Appleples, FilterFilter) {listar filtroplesbyappleApplefilter (listão> Appleples, FilterFilter) {listão): para (Final Apple Apple: Apples) {if (filtro.accept (Apple)) {filterapples.add (Apple);}} retorna filterApples;}Após a abstração do comportamento acima, podemos definir condições de filtro na chamada específica e passar as condições como parâmetros para o método. Neste momento, usamos o método de classe interna anônima:
public estático void main (string [] args) {list <pple> maçãs = new ArrayList <> (); // filtra a lista de maçãs <pple> filterapples = filterapplesbyappplefilter (maçãs, new AppleFilter () {@Overridepublic boolean Acep (maçã) {// filtro de pó com peso a mais de 100 do que 100g. Apple.getWeight ()> 100;}});}Esse design é frequentemente usado no JDK, como java.util.comparator, java.util.concurrent.lable, etc. Ao usar esse tipo de interface, podemos usar classes anônimas para especificar a lógica de execução específica da função nos locais de chamada específicos. No entanto, a partir do bloco de código acima, embora seja muito nerd, não é conciso o suficiente. Em Java8, podemos simplificá -lo através do Lambda:
// Filter Apple List <pple> filterapples = filterapplesbyapplefilter (maçãs, (Apple Apple) -> color.red.equals (Apple.getColor ()) && Apple.getweight ()> = 100); // () -> xxx () são os parâmetros do método e xxx é a implementação do método
2. Definição de expressão lambda
Podemos definir uma expressão lambda como uma função anônima concisa e aceitável. Primeiro de tudo, precisamos deixar claro que a expressão de Lambda é essencialmente uma função. Embora não pertença a uma classe específica, ele possui uma lista de parâmetros, corpo de função, tipo de retorno e capacidade de lançar exceções; Em segundo lugar, é anônimo, e a expressão de Lambda não possui um nome de função específico; A expressão lambda pode ser passada como parâmetros, simplificando bastante a escrita do código. A definição de formato é a seguinte:
Formato 1: Lista de parâmetros -> Expressão
Formato 2: Lista de parâmetros -> {Expression Collection}
Deve -se notar que a expressão de Lambda implica a palavra -chave de retorno; portanto, em uma única expressão, não precisamos escrever explicitamente a palavra -chave de retorno, mas quando a expressão é uma coleção de declarações, precisamos adicionar explicitamente retorno e incluir múltiplas expressões com aparelhos curly {}. Vamos ver alguns exemplos abaixo:
// Retorna o comprimento da sequência fornecida, devolução implicitamente (strings) -> s.Length () // Retorna sempre o método não reumentado () () -> 42 // contém várias linhas de expressão, fechadas em aparelhos encaracolados (int x, int y) -> {int z = y; retorno x + z;}3. Use expressões lambda com base em interfaces funcionais
O uso de expressões lambda requer a ajuda de interfaces funcionais, o que significa que somente quando a interface funcional aparece, podemos simplificá -las com expressões lambda.
Interface funcional personalizada:
As interfaces funcionais são definidas como interfaces que possuem apenas um método abstrato. A melhoria na definição de interface de Java8 é introduzir métodos padrão, para que possamos fornecer implementações padrão dos métodos na interface. No entanto, não importa quantos métodos padrão existam, desde que um tenha e apenas um método abstrato, é uma interface funcional, como segue (consulte o AppleFilter acima):
/*** Interface do filtro da Apple*/ @FunctionInterfacePublic Interface AppleFilter {/*** Condição do filtro Resumo ** @param Apple* @Return*/boolean Acep (Apple Apple);}O AppleFilter contém apenas um método abstrato aceita (Apple Apple). De acordo com a definição, ela pode ser considerada uma interface funcional. Ao definir, adicionamos a anotação @FunctionalInterface à interface para marcar a interface como uma interface funcional. No entanto, essa interface é opcional. Depois de adicionar essa interface, o compilador restringe a interface a ter apenas um método abstrato, caso contrário, será relatado um erro, por isso é recomendável adicionar essa anotação à interface funcional.
JDK vem com interface funcional:
O JDK é uma expressão de lambda com ricas interfaces funcionais. Abaixo estão exemplos de uso de predicado <T>, consumidor <T>, função <t, r> respectivamente.
Predicado:
@FunctionInterfacePublic Interface Predicate <t> {/*** Avalia isso prevendo o argumento dado.A função do predicada é semelhante ao AppleFilter acima. Ele usa as condições que definimos externamente para verificar os parâmetros de entrada e retorna o resultado da verificação booleano. O seguinte usa o predicado para filtrar os elementos da coleção de listas:
/**** Lista @param* @param predicado* @param <t>* @return*/public <t> List <T> filtro (lista <T> Lista, predicada <t> predicada) {list <t> newList = newRaRARARABList <T> (); para (final t: list) {if (predicado.test (t)) {newList.usar:
Demo.Filter (List, (String str) -> null! = str &&! str.isempty ());
Consumidor
@FunctionInterfacePublic Interface Consumer <T> {/*** executa esta operação no argumento dado. ** @param t O argumento de entrada*/void aceita (t);}O consumidor fornece uma função abstrata aceita que recebe parâmetros, mas não retorna valores. O seguinte usa o consumidor para atravessar a coleção.
/*** Traversal da coleção e execute um comportamento personalizado ** @param list* @param consumer* @param <t>*/public <t> filtro void (lista <t> list, consumidor <t> consumidor) {for (final t t: list) {consumer.accept (t);}}Usando a interface funcional acima, itere por meio da coleção de strings e imprima strings não vazios:
Demo.Filter (List, (String str) -> {if (stringUtils.isnotblank (str)) {System.out.println (str);}});Função
@FunctionInterfacePublic Função da interface <t, r> {/*** aplica esta função ao argumento dado.A função executa uma operação de conversão. A entrada são dados do tipo T e retorna dados do tipo R. A seguinte função usa para converter o conjunto:
public <t, r> list <r> filtro (lista <t> list, function <t, r> function) {list <r> newList = new ArrayList <R> (); para (final t t: list) {newList.add (function.apply (t));} retorna newList;}outro:
Demo.Filter (List, (String str) -> Integer.parseint (str));
As interfaces funcionais acima também fornecem algumas implementações padrão das operações lógicas. Vamos falar sobre isso mais tarde ao apresentar os métodos padrão da interface java8 ~
Algumas coisas a prestar atenção durante o uso:
Digite inferência:
Durante o processo de codificação, às vezes podemos nos perguntar qual interface funcional nosso código de chamada corresponderá. De fato, o compilador fará julgamentos corretos com base em parâmetros, tipo de retorno, tipo de exceção (se presente), etc.
Ao chamar de maneiras específicas, o tipo de parâmetro pode ser omitido em alguns momentos, simplificando ainda mais o código:
// Filter Apple List<Apple> filterApples = filterApplesByAppleFilter(apples,(Apple apple) -> Color.RED.equals(apple.getColor()) && apple.getWeight() >= 100);// In some cases, we can even omit parameter types, and the compiler will correctly judge List<Apple> filterApples = filterApplesByAppleFilter(apples,apple -> Color.red.equals (Apple.getColor ()) && Apple.getWeight ()> = 100);
Variáveis locais
Todos os exemplos acima de nossas expressões de lambda usam seus parâmetros do corpo, também podemos usar variáveis locais em lambda, como segue
int peso = 100; list <pple> filterapples = filterapplesbyapplefilter (maçãs, maçã -> color.red.equals (Apple.getColor ()) && Apple.getWeight ()> = peso);:
Neste exemplo, usamos o peso variável local no lambda. No entanto, o uso de variáveis locais no Lambda deve exigir que a variável seja explicitamente declarada como final ou de fato final. Isso ocorre principalmente porque a variável local é armazenada na pilha e a expressão de lambda é executada em outro thread. Quando a visualização do thread acessa a variável local, a variável tem a possibilidade de ser alterado ou reciclado; portanto, não haverá problemas de segurança de thread após a modificação no final.
4. Citação de método
O uso de referências de método pode tornar o código mais simplificado. Às vezes, essa simplificação faz com que o código pareça mais intuitivo. Vamos dar uma olhada em um exemplo:
/* ... omite a operação de inicialização de maçãs* /// use o lambda expressão Apples.sort ((Apple A, Apple B) -> Float.comPare (A.GetWeight (), B.GetWeight ())); // Use o método para se referir a Apples.Sort (comparador.comparing (Apple :: Getweight));
Referências de método Connecte a associação e o próprio método por meio de ::, que são divididos principalmente em três categorias:
Método estático
(args) -> ClassName.staticmethod (args)
Converter para
ClassName :: staticmethod
Método de exemplo de parâmetro
(args) -> args.instancemethod ()
Converter para
ClassName :: InstanceMethod // ClassName é Tipo args
Método de instância externa
(args) -> ext.instanceMethod (args)
Converter para
ext :: instanceMethod (args)
Consulte:
http://www.codeceo.com/article/lambda-of-java-8.html
O exposto acima é a expressão lambda do novo recurso JDK8 que o editor apresentou a você. Espero que seja útil para você. Se você tiver alguma dúvida, deixe -me uma mensagem e o editor responderá a você a tempo. Muito obrigado pelo seu apoio ao site wulin.com!