Java 8 - Collect elements from a list

2

Good morning.

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

For example:

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

Collecting positions 0 and 1 of each element of the ListList, 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()); 
    
asked by anonymous 02.01.2015 / 12:07

1 answer

1

Because the list does not change

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

The (Object[] e) excerpt declares a parameter for the function. In Java, if a parameter is given a new value assignment, does not change the original reference as it might with a pointer to pointers in C.

Therefore, the e = new Object[] {e[0], e[1]} snippet creates a new array which is then discarded as soon as the function terminates.

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

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

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

Solution

However, the map method can be used in conjunction 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 map method, other than peed , is intended 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 should return some value that will be used to mount the new list.

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

Complete sample 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());
    
02.01.2015 / 15:44