JAVA 8 – CARACTERÍSTICAS

Index de contido

Hoxe traémosvos este blog unha entrada sobre Java melloras 8. Teño que confesar, que aínda que ao principio parecía unha auténtica galimatías, co curso das horas e sobre todo, coa práctica das novas estruturas, estiven convencendo de que realmente o código é moito máis lexible , cómodo de implementar e máis importante: eficiente.

Ben, é certo que teño un bo momento para probar, aprender e fortalecer, pero hai estruturas e modos de traballo que fixeron a miña vida.

Entón, quizais o mesmo, tamén pode servirlle.

fluxo, con todos comezados en Java 8!

A diferenza do seu predecesor, Java 7, a súa versión máis recente (Java 8) engadiu á interface de colección (desde o paquete java.util) o método de transmisión.

/** * Returns a sequential {@code Stream} with this collection as its source. * *This method should be overridden when the {@link #spliterator()} * method cannot return a spliterator that is {@code IMMUTABLE}, * {@code CONCURRENT}, or late-binding. (See {@link #spliterator()} * for details.) * * @implSpec * The default implementation creates a sequential {@code Stream} from the * collection's {@code Spliterator}. * * @return a sequential {@code Stream} over the elements in this collection * @since 1.8 */ default Stream stream() { return StreamSupport.stream(spliterator(), false); }

¿Que é o fluxo? Ben, non máis ou menos que unha secuencia de elementos. Con este método podemos transformar unha colección de obxectos (matrices, listas …) nunha sucesión de obxectos.

Imos gravar como se empregou este método para clases de arraylist ou para matrices:

A interface da lista herda da colección, así que tamén poderá usar o método de transmisión polo que é fácil deducir o seguinte:

List listaCadenas = new ArrayList(); //Notación diamanteList listaCadenas = new ArrayList(); listaCadenas.add("Juan"); listaCadenas.add("Antonio"); listaCadenas.add("Maria"); Stream streamCadenas = listaCadenas.stream();En el caso de Arrays también podemos usar el método: public static Stream stream(T array) { return stream(array, 0, array.length); }Integer enteros = {1,2,3,4,5,6}; Stream enterosStream = Arrays.stream(enteros);Además del método stream Java 8 incluye otro método muy en la línea: parallelStream. Para más información: https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html#stream--

Perfecto, pero con isto que facemos? Shhh, tranquilidade … durmir un paso, suave suave … Ahem 😉 Continuar.

Java 8

mapa, O seu aliado

Aínda que a interface de transmisión proporciona varios métodos, imos comezar por isto: mapa.
Mentres que nas seguintes entradas non sairemos no esquecemento: filtro, flatmap e reducir.

Cantas veces? Viaxamos unha estrutura onde comprobamos unha condición que fixemos unha acción ou outra?
cantas liñas de código? Cantos por / si / máis aniñados de que o sonar queixouse (e pasamos algunhas semanas cando esquecemos o que fixo ese fragmento de código)?

Ben en Java 8 Estamos autorizados a facelo igual en unha liña.

Como antes de que o primeiro é presentarlle o método:

/** * Returns a stream consisting of the results of applying the given * function to the elements of this stream. * *This is an intermediate * operation. * * @param The element type of the new stream * @param mapper a non-interfering, * stateless * function to apply to each element * @return the new stream */ Stream map(Function mapper);

Aplicará unha función que chamemos f sobre cada un dos elementos da sucesión e devolverá outra sucesión de elementos xa modificados.

e esa función é …?

Calquera que teña que aplicar, que si cumprindo algúns Restricións.

Por exemplo, podemos dicir que queremos facer un recorte () a cada elemento da sucesión do tipo de corda da sucesión do primeiro elemento. Para iso podemos escribir como este en Java 8:

streamCadenas.map(s->s.trim());

É a forma en que comecei a usalo e con el aínda non o fago.
Nesta opción usamos unha variable s, cuxo alcance é o do método (fóra do mapa non existirá e non será necesario declaralo anteriormente).
Estamos indicando que cada elemento desa sucesión, Imos gardalo nunha variable s, do mesmo tipo do elemento, e imos aplicar a función Trim ().

Por que non poñemos STRING S- > s .trim ()? Porque Java recoñece perfectamente o tipo de variable s ao coñecer o tipo de elementos de sucesión (fluxo). Se usabamos o fluxo enterarosstream S sería o tipo de número enteiro e non sería necesario declaralo.

Outra forma de facer o mesmo sería o seguinte:

streamCadenas.map(String :: trim).

A diferenza coa anterior é que gardamos a variable, esta nomenclatura non sempre é válida. Debemos asegurarnos de que o método non teña parámetros, se os tiña, non se puido empregar deste xeito aínda que faga na súa primeira versión

filtro ou como gardar algúns loops

/** * Returns a stream consisting of the elements of this stream that match * the given predicate. * *This is an intermediate * operation. * * @param predicate a non-interfering, * stateless * predicate to apply to each element to determine if it * should be included * @return the new stream */ Stream filter(Predicate predicate);

Como na propia API está indicado, o filtro recibe unha sucesión de elementos e devolve a aqueles que cumpren co patrón buscado (predicado).

Comezamos a mostrar un exemplo básico.
Temos unha lista de cadeas nas que gardamos os tipos de vehículos e obteremos aqueles que non son “motos”

List vehicles = Arrays.asList("car", "motorbike", "bus");Antes haríamos algo de este tipo:List filteredVehicles = new ArrayList(); for(String vehicle: vehicles){ if(!"motorbike".equals(vehicle)){ filteredVehicles.add(vehicle); } }

con Java 8 sería tal como:

List filteredVehicles = vehicles.stream() .filter(v -> !"motorbike".equals(v)) .collect(Collectors.toList());

No noso caso, xa por un proxecto, tivemos unha lista de tipo de perfil chamado perfís onde Tivemos casos de varios tipos: individual, corporativo, … Queriamos que a lista obteña tres. Un para cada tipo de perfil dos que consistía na aplicación.

Ao principio recorremos ao / se no que imos a lista de perfís e, se especificamos a condición a cumprir. Como había varias listas que queriamos como unha saída era necesario usar se / máis anidado. Finalmente conseguimos moito máis limpo con este método Java 8. Debaixo do exemplo dunha das listas obtidas.

Neste caso, o importante é ver outro tipo de estrutura onde o predicado do filtro é outro método: ISTYPE, un método propio.

List individuales = profiles.stream().filter(s -> isType(s, EnumTypeCertificate.INDIVIDUAL.name())).collect(Collectors.toList());private boolean isType(Profile profile,String typeProfile) { return profile.getType().equals(typeProfile); }flatMap, magia!/** * Returns a stream consisting of the results of replacing each element of * this stream with the contents of a mapped stream produced by applying * the provided mapping function to each element. Each mapped stream is * {@link java.util.stream.BaseStream#close() closed} after its contents * have been placed into this stream. (If a mapped stream is {@code null} * an empty stream is used, instead.) * *This is an intermediate * operation. * * @apiNote * The {@code flatMap()} operation has the effect of applying a one-to-many * transformation to the elements of the stream, and then flattening the * resulting elements into a new stream. * *Examples. * *If {@code orders} is a stream of purchase orders, and each purchase * order contains a collection of line items, then the following produces a * stream containing all the line items in all the orders: *{@code * orders.flatMap(order -> order.getLineItems().stream())... * }* *If {@code path} is the path to a file, then the following produces a * stream of the {@code words} contained in that file: *{@code * Stream lines = Files.lines(path, StandardCharsets.UTF_8); * Stream words = lines.flatMap(line -> Stream.of(line.split(" +"))); * }* The {@code mapper} function passed to {@code flatMap} splits a line, * using a simple regular expression, into an array of words, and then * creates a stream of words from that array. * * @param The element type of the new stream * @param mapper a non-interfering, * stateless * function to apply to each element which produces a stream * of new values * @return the new stream */ Stream flatMap(Function<? super T, ? extends Stream> mapper);

No exemplo que vemos a continuación tivemos o seguinte problema. Cada elemento de perfil tiña un campo de cadea de tipo token que contiña valores separados por coma.
Queriamos obter cada un deses elementos e engadilos a unha lista pero sen elementos repetidos.

Para isto co mapa Tranformammo Lista de obxectos de perfil nunha sucesión de elementos aos que se aplicou para o seu token variable o método dividido.

Imaxina que temos algo así

public class Profile { String token; ... //Getters and Setters ... }

O campo Token ten un valor como este = > token = “navegador, pcs12, jks”; agora imaxino que temos dous obxectos de perfil que teriamos Algo así:

Lista de Profile Profile = > token = "BROWSER,PKCS12,JKS,USER_GENERATED,JKS,SOFT" ...

O que pretendemos obter é:

Lista de String "BROWSER" "PKCS12" "JKS" "USER_GENERATED" "SOFT"

E aínda máis, non queremos en realidade a lista, queriamos devolver falso ou verdadeiro dependendo de se o perfil contiña calquera dos tokens polo que se debe mostrar na pantalla.

profiles.stream() .map(s->StringUtils.split(s.getToken(), ",")) .flatMap(Arrays::stream) .distinct() .map(StringUtils::trim) .collect(Collectors.toList()) .stream() .anyMatch(EnumToken::isShowInMenu);

Para rematar o OS deixamos o capítulo 1, descarga gratuita, desde Doc Java 8: (Prema aquí)

Esta publicación foi modificada o 19 de xaneiro de 2021 13:07

Deixa unha resposta

O teu enderezo electrónico non se publicará Os campos obrigatorios están marcados con *