Anđela Todorović
Anđela Todorović

Reputation: 71

How to access individual objects stream inside of nested stream in Java 8?

Given a list of integer pairs (to simplify the problem and avoid Pair data structure in Java, we'll use list of lists), how to manipulate individual integers in them?

For example, I have loaded n points by coordinates (x,y).

List<List<Integer>> numbers;
Scanner sc = new Scanner(System.in);                
int x = sc.nextInt();
int y = sc.nextInt();
numbers.add(Arrays.asList(x,y));
sc.close();

Now I want to convert them to stream and check if each of the coordinates x and y satisfy that x*y < 0.

I've tried to use flatmap but can't convert inner lists to stream

Upvotes: 0

Views: 594

Answers (3)

BeerBear
BeerBear

Reputation: 23

Just now you asked a question. When I came back after writing the answer, your question was closed. I have to answer the question you just asked under this question.

package lambda;

import java.util.*;

import static java.util.stream.Collectors.*;

/**
 * @Author: Beer Bear
 * @Description: todo
 * @Date: 2021/6/29 10:41
 */
public class stackoverflow {
    public static void main(String[] args) {
        List<Integer> list1 = Arrays.asList(1,2);
        List<Integer> list2 = Arrays.asList(-1,2);
        List<Integer> list3 = Arrays.asList(1,100);
        List<List<Integer>> numbers = new LinkedList();
        numbers.add(list1);
        numbers.add(list2);
        numbers.add(list3);
        //System.out.println(allList);
        Map<Boolean, List<Integer>> map = numbers.stream().collect(groupingBy(list -> list.get(0) * list.get(1) > 0, mapping(list -> function(list.get(0), list.get(1)), toList())));
        System.out.println(map);
        int sumOfCase1 = map.get(true).stream().mapToInt(item -> item).sum();
        int sumOfCase2 = map.get(false).stream().mapToInt(item -> item).sum();
        System.out.println(sumOfCase1+" "+sumOfCase2);
    }
    private static int function(int a, int b){
        return a+b;
    }
}

Upvotes: 0

Vimit Dhawan
Vimit Dhawan

Reputation: 677

you can convert the inner list to stream but the flat map is used to flatten the list. it will give you one element, not a pair.

List<Integer> list = numbers.stream().flatMap(point -> point.stream()).filter(x -> x>0).collect(Collectors.toList());

Upvotes: 0

rzwitserloot
rzwitserloot

Reputation: 102822

Java is nominal, as in, it likes names of things.

You're fighting the language. Stop doing that. Go with the flow.

List<Integer> could indeed be used to represent a point, but it's real shite at it. It doesn't print nicely, and it is trivial to make an 'invalid state' object - List.of(), what coordinate is that? List.of(1, 2, 3), what's going on there?

Make a class that represents the idea of a 2D point.

public record Point(int x, int y) {}

will do that, for exmaple.

But, let's say you want to keep shooting yourself in the foot and abuse List<Integer> as a coordinate pair, you do not want flatmap.

Given, say, the origin coordinate ((0, 0)), as well as x=5 and y=10, then flatMap would let you obtain a stream that is just the sequence 0, 0, 5, 10. This is not good - streams work by letting you inspect and operate on individual items. There's no way to check x * y at that point.

So, you don't want flatmap. You'd just operate on your numbers.stream(), which is a stream of List<Integer> objects. You can then apply your logic to each of these objects, which are just a real bad way of representing 2D coordinates.

numbers.stream().anyMatch(list -> list.get(0) * list.get(1) < 0);

Upvotes: 3

Related Questions