Convertire metodo in Java 8 - Stream

di il
7 risposte

Convertire metodo in Java 8 - Stream

Salve a tutti

Ho un metodo abbastanza semplice che svolge le seguenti azioni:
- Itera per il primo indice della matrice
- Itera per il secondo indice della matrice
- Memorizza il valore Stringa i-esimo della matrice in una variabile d'appoggio
- Fa delle operazioni tra Stringhe quali replaceAll e aggiunge testo prestabilito.
- Salva questo valore in un nuovo ArrayList<String>

Poi successivamente:
- Creo una variabile d'appoggio
- Prendo un file di testo e lo "splitto"
- Controllo se la riga-iesima splittata contiene una parola e nel caso faccio un substring
- Aggiungo la riga nella variabile d'appoggio
- Aggiungo il valore i-esimo dell'ArrayList<String> di prima nella variabile d'appoggio
- Ritorno la variabile d'appoggio

Giusto per fare chiarezza in sostanza la prima parte del metodo si occupa di recuperare dei valori da una matrice[j] e unire in una nuova stringa tutto l'indice J-esimo. Fare operazioni su questa nuova stringa e poi salvarla in un nuovo Array di indice i che chiamiamo ArraydiStringhe.
La seconda parte del metodo parte da un file di testo, il quale viene splittato per righe e nel quale vengono modificate alcune di queste righe, aggiungendo tra l'altro alcune informazioni contenute in ArraydiStringhe.
Il contenuto nel mentre viene memorizzato in una variabile d'appoggio che poi sarà ritornata dal metodo.

Dovrei convertire questo metodo in Java 8 ed eseguire tutte queste operazioni con gli Stream, ma non sono molto ferrato.
Qualcuno di voi potrebbe mostrarmi da dove partire e quali metodi di Stream utilizzare per ottenere lo stesso risultato in Java 8?

Ps: che bello un forum di Programmazione attivo

7 Risposte

  • Re: Convertire metodo in Java 8 - Stream

    Zed92 ha scritto:


    Dovrei convertire questo metodo in Java 8 ed eseguire tutte queste operazioni con gli Stream, ma non sono molto ferrato.
    Qualcuno di voi potrebbe mostrarmi da dove partire e quali metodi di Stream utilizzare per ottenere lo stesso risultato in Java 8?
    Quello che hai descritto non mi pare "banale", comunque ti posso dare un breve esempio da cui puoi partire.
    import java.util.Arrays;
    import java.util.stream.Collectors;
    
    public class StreamDiMatriceString {
        public static void main(String[] args) {
            String[][] matrice = {
                { "ciao"   , "prova"    },
                { "matrice", "stringhe" },
            };
    
            String resultString = Arrays.stream(matrice)
                .flatMap(subarr -> Arrays.stream(subarr))
                .map(elem -> elem.toUpperCase())
                .collect(Collectors.joining(","));
    
            System.out.println(resultString);
        }
    }
    Prima ottengo lo Stream dell'array principale della matrice, poi per ciascun elemento (che è un array!) ottengo il suo Stream e tramite flatMap "appiattisco" tutti questi sotto-stream in un unico stream. A quel punto diventa semplice: con map altero ciascun elemento (nell'esempio metto la stringa in upper-case) e poi alla fine colleziono tutte le stringhe con un Collector predefinito (fornito dal joining() ) per unire tutte le stringhe usando anche un separatore (",").

    Alla fine ottengo una unica stringa "CIAO,PROVA,MATRICE,STRINGHE"
  • Re: Convertire metodo in Java 8 - Stream

    Ciao andbin e grazie per la risposta.

    Ho provato il codice e sembra funzionare in parte.

    Quello che fa il tuo codice sembra essere di stampare linearmente tutta la matrice, mentre a me serviva eliminare solamente un'indice della matrice e quindi generare i-stringhe e inserirle in una nuova collezione/array per poi richiamarle.

    Quindi nel tuo caso, invece di ottenere "ciao,prova,matrice,stringhe"; io vorrei ottenere "ciao, prova" e "matrice, stringhe"; magari direttamente in un nuovo array ordinato.
  • Re: Convertire metodo in Java 8 - Stream

    Zed92 ha scritto:


    Quello che fa il tuo codice sembra essere di stampare linearmente tutta la matrice, mentre a me serviva eliminare solamente un'indice della matrice e quindi generare i-stringhe e inserirle in una nuova collezione/array per poi richiamarle.
    Io ti ho solo fatto un esempio basilare per farti vedere come gestire gli stream a fronte di un array bidimensionale. Giusto per "partire". Il resto spetta a te .....
  • Re: Convertire metodo in Java 8 - Stream

    Ci provo
  • Re: Convertire metodo in Java 8 - Stream

    String resultString = Arrays.stream(matrice)
                    .flatMap(subarr -> Arrays.stream(subarr))
    Il codice crea un flusso di stream di tutta la matrice e poi con flatMap la appiattisce in un unico stream.
    Io invece voglio lavorare con la matrice riga per riga, quindi mi servirebbe una funzione che mi crei un flusso di stream per ogni colonna.
    Sto Googlando da un po ma ancora non ho trovato nessuna funzione del genere.

    Edit:
    Per ora sono riuscito a farlo solamente cosi, ma credo sia possibile eliminare il ciclo esterno con un'altra funzione di stream giusto?
    		//Itero per gli strati
    	    for(int i=0;i<matricePesi.length;i++){
    	    	String resultString = Arrays.stream(matricePesi[i])
    	               .map(elem -> (""+elem).replaceAll(" ", "").replaceAll(".0,", ",").replaceAll(".0]", "]").replaceAll("null", ""))
    	               .collect(Collectors.joining(""));
    	    	pesiPerStrato.add(resultString.replaceAll("\\]\\[", "\\],\\["));
    	    }
  • Re: Convertire metodo in Java 8 - Stream

    Zed92 ha scritto:


    Io invece voglio lavorare con la matrice riga per riga, quindi mi servirebbe una funzione che mi crei un flusso di stream per ogni colonna.
    Manipolare una colonna specifica predefinita è facile, altro esempio basilare:
    String[][] matrice = {
        { "aaa", "bbb", "ccc" },
        { "ddd", "eee", "fff" },
        { "ggg", "hhh", "iii" },
    };
    
    String resultString = Arrays.stream(matrice)
        .map(subarr -> subarr[1])     // elemento in seconda colonna
        .collect(Collectors.joining(","));

    In resultString ho "bbb,eee,hhh".

    Se vuoi uno stream che prenda tutti i dati prima in colonna 0, poi in colonna 1 ecc.... credo che si possa sicuramente fare, in un modo o nell'altro, ma è chiaramente un pochino più complesso.
  • Re: Convertire metodo in Java 8 - Stream

    Questo invece scansiona la matrice "per colonne". Funzionante a condizione che: a) ci sia almeno una riga; b) l'array sia "rettangolare" (e non "jagged")
    String[][] matrice = {
            { "aaa", "bbb", "ccc" },
            { "ddd", "eee", "fff" },
            { "ggg", "hhh", "iii" },
    };
    
    String resultString = IntStream.range(0, matrice[0].length)
            .boxed()
            .flatMap(indiceColonna -> Arrays.stream(matrice)
                    .map(subarr -> subarr[indiceColonna]))
            .collect(Collectors.joining(","));
    resultString contiene "aaa,ddd,ggg,bbb,eee,hhh,ccc,fff,iii"
    Ovvero: prima tutti i dati della colonna 0, poi tutti i dati della colonna 1, ecc...

    Probabilmente (sicuramente) non è il massimo e si può fare di meglio ma ... in questo momento non ho tempo di approfondire.

    Ripeto: questi sono sempre "esempi" da cui puoi prendere spunto.
Devi accedere o registrarti per scrivere nel forum
7 risposte