Doubts regarding the use of the Java 8 stream

Asked

Viewed 247 times

3

I’m practicing some new things that came with Java 8 and between those the use of Stream. I have heard that when we do some action in a list using the stream, it does not change the value of the original list, for example:

List<String> lista = Arrays.asList("a", "c", "b");

lista.stream().sorted(Collector.comparing(String::toString)).forEach(System.out::println);

//saída
//a, b, c

lista.forEach(System.out::println);

//saída
//a, c, b

Well, so far so good, but let’s say I have this scenario:

import java.util.ArrayList;
import java.util.List;

public class Teste {

    public static void main(String[] args) {

        List<Pessoa> lista = new ArrayList<Teste.Pessoa>();
        lista.add(new Pessoa("Paulo", "Gustavo"));
        lista.add(new Pessoa("Bla", "Ble"));

        Pessoa pessoa = lista.get(0);
        System.out.println(pessoa);

        mudaValor(lista);
        System.out.println(pessoa);
    }

    public static void mudaValor(List<Pessoa> lista) {
        lista.stream().forEach(pessoa -> {
            pessoa.setNome("Joquino");
        });
    }

    static class Pessoa {

        private String nome;
        private String sobreNome;

        public Pessoa(String nome, String sobreNome) {
            this.nome = nome;
            this.sobreNome = sobreNome;
        }

        public String getNome() {
            return nome;
        }

        public void setNome(String nome) {
            this.nome = nome;
        }

        public String getSobreNome() {
            return sobreNome;
        }

        public void setSobreNome(String sobreNome) {
            this.sobreNome = sobreNome;
        }

        @Override
        public String toString() {
            return nome;
        }
    }
}

My question is: why did my personal object have its value changed since it was changed in stream() that theoretically does not change the value of the actual list?

The person object is with memory reference to the same object on the list, right? Only if the change was made in the stream, it should not have kept the value?

2 answers

4

You are confusing things.

lista.stream().sorted() returns a new Stream (copy of lista ordered). Your "list" collection remains unchanged.

However, both collections have references to the same objects.

  • Uhum, I figured so. It was doubtful, as I thought that the stream would never change the value of the list with these actions of for example, Sort, I thought it would also serve for other operations involving the values of the list. Thank you very much

4


Paulo Gustavo, what happens in his code is that when invoking the method stream on your list, in fact you have generated a new Stream, not a new instance of ArrayList, and even if you had generated a new instance, see what would happen, which in this case is implemented by ArrayList<T>.

The class to ArrayList<E> internally keeps the values in a array:

class ArrayList<E> extends AbstractList, implements RandomAcces{
     private transient Object[] elementData;
}

You may generate other Collections from the initial, as well as streams, but the array will have references to their objects still (from Collection initial).

  • Thank you for clarifying, the answers are being of great help.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.