Indice del contenuto
Oggi ti porto questo blog una voce di Java Miglioramenti 8. Devo confessare, che anche se all’inizio sembrava un’autentica galimazia, con il corso delle ore e soprattutto, con la pratica delle nuove strutture, sono stato convincente che davvero il codice è molto più leggibile , comodo da implementare e, cosa più importante: efficiente.
Beh, è vero che mi diverto a provare, imparare e rafforzare ma ci sono strutture e modalità di lavoro che hanno reso la mia vita.
Così, forse lo stesso, puoi anche servirti.
Stream, con tutti voi è iniziato a Java 8!
A differenza del tuo predecessore, Java 7, la sua versione più recente (Java 8) ha aggiunto all’interfaccia di raccolta (dal pacchetto Java.util) il metodo del flusso.
/** * 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); }
Cos’è il flusso? Bene, non più o meno di una sequenza di elementi. Con questo metodo possiamo trasformare una raccolta di oggetti (arrays, lists, …) in una successione di oggetti.
Registreremo come questo metodo è stato utilizzato per le classi Arraylist o per gli array:
L’interfaccia di elenco eredita dalla raccolta Allora qualsiasi tipo che sarà anche in grado di utilizzare il metodo del flusso in modo che sia facile dedurre quanto segue:
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--
Perfetto, ma e con questo cosa facciamo? Shhh, tranquillità … Dormi un passo, morbido morbido … Ahem 😉 Continuiamo.
Mappa, Il tuo alleato
Sebbene l’interfaccia del flusso fornisca diversi metodi, inizieremo da questo: mappa.
mentre nelle seguenti voci non lasceremo in oblio: filtro, flatmap e ridurre.
Quante volte? Abbiamo viaggiato una struttura in cui controllarci una condizione abbiamo fatto un’azione o un’altra?
Quante linee di codice? Quanti per / IF / Else annidati da cui si è lamentato il sonar (e siamo passati alcune settimane quando abbiamo dimenticato cosa ha fatto quel frammento del codice)?
Bene in Java 8 ci è permesso di fare lo stesso in Una linea.
Come prima della prima cosa è di presentarti il metodo:
/** * 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);
La mappa applicherà una funzione che chiamiamo f Busta ciascuno degli elementi della successione e restituirà un’altra successione di elementi già modificati.
E quella funzione è …?
Chiunque abbia bisogno di applicare, che sì che soddisfa alcuni Restrizioni.
Ad esempio, possiamo dire che vogliamo fare un trim () a ciascun elemento della successione del tipo di stringa della successione del primo elemento. Per questo possiamo scriverlo come questo in Java 8:
streamCadenas.map(s->s.trim());
È il modo in cui ho iniziato a usarlo e con esso non sono ancora l’unico.
In questa opzione usiamo una variabile S, il cui ambito è quello del metodo (al di fuori della mappa non esisterà e non sarà necessario dichiararlo in precedenza).
stiamo indicando che ogni elemento di tale successione, Stiamo per salverlo in una variabile s, dello stesso tipo di elemento e avremo intenzione di applicare la funzione Trim ().
Perché non abbiamo messo String S- > s .trim ()? Poiché Java riconosce perfettamente il tipo di variabile con conoscere il tipo di elementi di successione (stream). Se avessimo usato il flusso enterrosstream s sarebbe il tipo intero e non sarebbe necessario dichiararlo.
Un altro modo per fare lo stesso sarebbe quanto segue:
streamCadenas.map(String :: trim).
La differenza con quella precedente è che abbiamo salvato la variabile, questa nomenclatura non è sempre valida. Dobbiamo assicurarci che il metodo non abbia parametri, se li avessi, non poteva essere usato in questo modo anche se lo fa nella prima versione
filtro o come salvare alcuni anelli
/** * 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);
Come nell’aPI stesso è indicato, il filtro riceve una successione di elementi e restituisce coloro che sono conformi al modello cercato (predicato).
Abbiamo iniziato a mostrare un esempio di base.
Abbiamo un elenco di catene in cui manteniamo i tipi di veicoli e prenderemo coloro che non sono “moto”
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 sarebbe tale come:
List filteredVehicles = vehicles.stream() .filter(v -> !"motorbike".equals(v)) .collect(Collectors.toList());
Nel nostro caso, già per un progetto, abbiamo avuto un elenco di tipo di profilo chiamato Profili dove Abbiamo avuto istanze di vario tipo: individuo, aziendale, … Volevamo che la lista abbia tre. Uno per ogni tipo di profilo di quelli che consistevano nell’applicazione.
All’inizio abbiamo fatto ricorso al per / se in cui abbiamo istituito la lista dei profili e nel se abbiamo specificato la condizione da soddisfare. Poiché c’erano diverse liste che volevamo come un’uscita era necessaria per usare se / altro nidificato. Alla fine abbiamo avuto molto più pulito con questo metodo Java 8. Sotto l’esempio di uno degli elenchi ottenuti.
In questo caso, l’importante è vedere un altro tipo di struttura in cui il predicato del filtro è un altro metodo: ISTYPE, un metodo proprio.
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);
Nell’esempio vediamo di seguito abbiamo avuto il seguente problema. Ogni elemento del profilo aveva un campo a catena di tipo token che conteneva valori separati dalla virgola.
Abbiamo voluto ottenere ciascuno di quegli elementi e aggiungerli a una lista ma senza elementi ripetuti.
Per questo Con la mappa Tranformammo Elenco di oggetti del profilo in una successione di elementi a cui è stato applicato per il suo token variabile il metodo diviso.
Immagina di avere qualcosa come questo
public class Profile { String token; ... //Getters and Setters ... }
Il campo token ha un valore come questo = > token = “browser, PKCS12, JKS”; ora immagino di avere due oggetti di profilo che avremmo avuto qualcosa del genere:
Lista de Profile Profile = > token = "BROWSER,PKCS12,JKS,USER_GENERATED,JKS,SOFT" ...
Cosa intendiamo ottenere è questo:
Lista de String "BROWSER" "PKCS12" "JKS" "USER_GENERATED" "SOFT"
E ancora di più, non volevamo in realtà la lista, volevamo restituire falsi o veri a seconda che il profilo contenesse uno dei token in modo da poter essere visualizzato sullo schermo.
profiles.stream() .map(s->StringUtils.split(s.getToken(), ",")) .flatMap(Arrays::stream) .distinct() .map(StringUtils::trim) .collect(Collectors.toList()) .stream() .anyMatch(EnumToken::isShowInMenu);
Per terminare il sistema operativo lasceviamo il capitolo 1, download gratuito, da DOC Java 8: (Clicca qui)
Questo post è stato modificato il 19 gennaio 2021 13:07