Não vou escrever a parte da sintaxe, vamos apenas levantar uma pergunta prática para ver quais conveniências esses novos recursos do Java8 podem trazer para nós.
A propósito, é usada alguma programação genérica, tudo é para simplificar o código
Cena:
Uma classe de dados que registra informações dos funcionários
Public class Employee {Nome da String Public; INT AGRIBUIL PÚBLICA; sexo público de char; Public String Time; Salário Público Int;}Temos uma coluna desse tipo de dados
Lista <Eplevy> Data = Arrays.asList (E1, E2, E3 ......)
Há uma necessidade agora: funcionários do grupo funcionários pela carta inicial de seus nomes (supondo que sejam todos nomes em inglês):
Então, o resultado que queremos obter deve ser um relacionamento de mapeamento como Map:char -> List<Employee>
mapa estático público <caractere, list <weeene>> groupbyfirstchar (list <cleomem> dados) {map <caractere, list <cleame>> resultado = new hashmap <> (); para (funcionário e: dados) {caractere c = e.name.charat (0); List <Eplete> l = resultado.get (c); if (l == null) {l = new ArrayList <> (); resultado.put (c, l); } l.add (e); } resultado de retorno;}O código não é complicado e pode ser concluído em breve. O chefe vê que você é tão eficiente, então ele disse que você o dividirá em grupos de acordo com o seu salário, para aqueles abaixo de 5.000, 5.000 ~ 10.000 ... etc.
Não será muito difícil, basta mudar a chave e processar um pouco logicamente
mapa estático público <string, list <cleame>> groupbysalary (list <cleomem> data) {map <string, list <cleame>> resultado = new hashmap <> (); for (funcionário e: dados) {string key = separado (e.salary); List <Eplement> l = resultado.get (chave); if (l == null) {l = new ArrayList <> (); resultado.put (chave, l); } l.add (e); } return resultado; <br>} string estática privada separada (int salário) {if (salário <= 5000) {return "menos de 5000"; } if (salário <= 10000) {return "5000 ~ 10000"; } if (salário <= 20000) {return "10000 ~ 20000"; } retornar "acima de 20000"}Então o chefe disse novamente, vamos dividir os funcionários em grupos de acordo com o ano de emprego. . .
Não vou escrever o código aqui. Se você compará -lo, descobrirá que, não importa como você agrupa, a única alteração é a maneira de selecionar o valor da chave.
A primeira letra de nome do funcionário é usada como a chave pela primeira vez:
Funcionário e -> e.name.Charat (0)
Na segunda vez, converto o salário do funcionário em string como chave de acordo com o método separat:
Funcionário E -> Separado (E. Salário): String
E assim por diante
Funcionário e -> getyear (e.time): string
De fato, a primeira vez que você também pode escrever a primeira letra em um único método.
Funcionário e -> getfirstchar (e.name): caractere
Para parecer mais bonitas, podemos dizer que os parâmetros dos três métodos estão definidos para o funcionário. O corpo do método não está escrito. Somente os parâmetros e os valores de retorno estão listados aqui.
Funcionário e -> getfirstchar (e): caracterizador e -> separado (e): stringemployee e -> getyear (e): string
O lado esquerdo de -> é o parâmetro, o lado direito de: é o valor de retorno e o lado direito de -> é a assinatura do método
Então, naturalmente, pensaremos em extrair a parte alterada como parâmetros e outras partes inalteradas como corpos de métodos, para que possamos omitir o código duplicado. Obviamente, a parte alterada é o método listado acima, que converte o funcionário e em chave, mas sabemos que o Java não pode passar os métodos como parâmetros. No entanto, isso não é um problema para os programadores com um pouco de experiência. Podemos usar interfaces para atingir nossos objetivos e, ao mesmo tempo, encontraremos outro problema. Os valores de retorno dos três métodos acima são diferentes; portanto, precisamos usar genéricos:
public static <k> map <k, list <cômio>> groupByKey (list <cleomem> dados, getKey <k> getKey) {map <k, list <cleame>> resultado = new hashmap <> (); para (funcionário e: dados) {k key = getKey.getKey (e); List <Eplement> l = resultado.get (chave); if (l == null) {l = new ArrayList <> (); resultado.put (chave, l); } l.add (e); } return resultado;} interface getKey <k> {k getKey (funcionário e);}Então o primeiro requisito acima pode ser realizado dessa maneira
Mapa <caractere, list <funcionário >> resultado = groupByKey (dados, new getKey <acharacter> () {@Override public caracteres getKey (funcionário e) {e.name.charat (0);}});O segundo requisito
Mapa <string, list <cleame>> resultado = groupByKey (list, new getKey <tring> () {@Override public String getKey (funcionário e) {separa (e.salary);}});Pode -se descobrir que precisamos apenas alterar os parâmetros genéricos e a implementação de classes internas anônimas. O único problema é que não é muito realista, e muitos códigos de rotina se refletem especialmente nas classes internas anônimas.
De fato, nos preocupamos apenas com os parâmetros e retornamos valores desta classe interna anônima, e o restante são apenas requisitos de sintaxe.
Java8 por acaso nos fornece uma boa maneira de evitar rotinas complicadas: expressões lambda, a implementação acima pode ser escrita como
Mapa <caractere, list <cleame>> resultadobyfirstchar = groupByKey (list, e -> e.name.charat (0)); map <string, list <cleomem>> resultbySalary = groupByKey (list, e -> separado (e.salary));
As expressões lambda mostram apenas o que nos preocupamos, parâmetros e valores de retorno. Ao mesmo tempo, devido à inferência de tipo, os tipos de parâmetros podem ser omitidos. A sintaxe específica não será introduzida aqui. Muita informação pode ser encontrada na internet
extra:
Se você tem um bom entendimento dos genéricos, o Method GroupByKey pode ser abstraído mais:
public static <k, e> map <k, list <e>> Grupo (list <? Extende e> dados, function <? super e ,? estende k> diversão) {map <k, list <e>> resultado = new hashmap <> (); para (e e: dados) {k k = fun.apply (e); <br> list <e> l = resultado.get (k); if (l == null) {l = new ArrayList <> (); resultado.put (k, l); } l.add (e); } Retornar resultado; <br>}Também extraímos a classe de funcionários, e os benefícios são óbvios
A interface da função é uma interface recém -adicionada ao Java8:
@FunctionAlInterfacePublic Interface Função <t, r> {r Aplicar (t t);}Digite um tipo T para retornar ao tipo R. A combinação de genéricos e programação funcional é muito boa. Embora os novos recursos do Java8 tenham sido criticados por vários tipos de reclamações, é sempre bom trazer benefícios, o que nos dá mais opções.
Se você tiver tempo, apresentarei o Stream, outra ótima ferramenta para Java8
O exposto acima é a aplicação de expressões Lambda no Java 8 e algum conhecimento relacionado genérico introduzido a você pelo editor. 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!