Doubts about using the Java 8 stream

3

I'm practicing some new things that came with Java 8 and among those using Stream. I have heard in a place 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, that's fine, but let's just 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 person object have its value changed since it was changed in stream() which theoretically does not change the value of the real list?

The person object is referenced from the same memory object list, right? But if the change was made to the stream, should not it have kept the value?

    
asked by anonymous 03.06.2015 / 13:57

2 answers

4

Paulo Gustavo, what happens in your code is that invoking the stream method in your list, in fact you 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 the case is implemented by ArrayList<T> .

The class a ArrayList<E> internally stores the values in an array :

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

You can generate other collections from the start, like streams , but the array will still have references to your objects (from the collection ).

    
03.06.2015 / 15:29
4

You're 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.

    
03.06.2015 / 14:51