Java 8 - Collecting elements from a list

Asked

Viewed 2,885 times

2

Good morning.

I would like to collect specific elements from a list. I could do the Java 7 style, but I’m curious to know how I would do in the Java 8 style.

For example:

[[1, 2, 3], [1, 2, 3], [4, 5, 6]] = An Object Arraylist[]

Collecting the positions 0 and 1 of each element of the arrayList, the expected result:

[[1, 2], [1, 2], [4, 5]]

Try as follows, but the list remains unchanged:

lista = lista.stream().peek((Object[] e) -> e = new Object[] {e[0], e[1]}).collect(Collectors.toList()); 
  • Hello, Breno! Welcome to [en.so]! This code does not work because it simply changes the variable reference (parameter) e for a new array, but without changing the original list. This technique might work if Java supported pointers.

1 answer

1


Because the list doesn’t change

The method peek returns the same original list which in this case remains unchanged because its lambda function does not alter the elements.

The excerpt (Object[] e) declares a parameter for the function. In Java, if a parameter receives an assignment of a new value it does not change the original reference as may happen with a pointer for C pointers.

Therefore, the excerpt e = new Object[] {e[0], e[1]} creates a new array that is however discarded as soon as the function ends.

The lambda function code of the peek is equivalent to the following:

void accept(Object[] e) {
    e = new Object[] {e[0], e[1]}
}

This confusion about parameters is common in Java, so much so that some authors always recommend using the modifier final in parameters, not to confuse them with local variables and not to find that you can modify them.

Solution

However, the method map can be used together with the lambda function to achieve the desired goal.

Example:

lista.stream()
    .map((Object[] e) -> new Object[] {e[0], e[1]})
    .collect(Collectors.toList());

The method map, other than peed, aims to create a new list based on the modified elements of the original vector.

The lambda function receives the elements from the original list and must return some value that will be used to assemble the new list.

Note that you do not need a return or an assignment to e. The value "returned" by the command from within the lambda function is already considered a return.

Full example code:

List<Object[]> lista = new ArrayList<Object[]>();
lista.add(new Object[] {1, 2, 3});
lista.add(new Object[] {1, 2, 3});
lista.add(new Object[] {4, 5, 6});
List<Object[]> novaLista = lista.stream()
    .map((Object[] e) -> new Object[] {e[0], e[1]}).collect(Collectors.toList());
  • 1

    It worked perfectly. Initially I had seen the map, but what I found was just mapped a single value, not multiples.

Browser other questions tagged

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