简体   繁体   English

使用流在java中进行内连接

[英]inner join in java using streams

I have two List Map: 我有两个列表地图:

orders 命令

[
    {
        item_id=1, 
        item=item-1, 
        user_id=1
    },
    {
        item_id=2, 
        item=item-2, 
        user_id=2
    }, 
    {
        item_id=3, 
        item=item-3, 
        user_id=3
    }
]

users 用户

[
    {
        user_id=1, 
        name=abh, 
        email=abh@bit.com
    }, 
    {
        user_id=2, 
        name=pol, 
        email=pol@bit.com
    }, 
    {
        user_id=3, 
        name=tre, 
        email=tre@bit.com
    }
]

They are initialized as 它们被初始化为

List<Map<String, String>> data

I want to do an sql equivalent inner join on this List Maps using Streams. 我想使用Streams在此List Maps上进行sql等效内连接。

I tried this: 我试过这个:

List<Map<String, String>> collect = leftData.stream().flatMap(t1 -> rightData.stream())
                .filter(t -> t.get(joinColumnTableLeft).equals(t.get(joinColumnTableRight)))
                .collect(Collectors.toList());

This gives me a result of size size(users) * size(orders), which is 9. And the collect has orders . 这给了我一个尺寸大小(用户)*大小(订单)的结果,这是9.并且收集有orders

But I want both the Map to merged into single and then create a list out of it. 但是我想要将Map合并为单个,然后创建一个列表。

Cannot use any library as of now. 截至目前无法使用任何库。

Assuming that you don't have duplicate entries (by the merge column key), you can use a method like this to merge. 假设您没有重复的条目(通过合并列键),您可以使用这样的方法进行合并。

This creates a map of the mergeColumn key to the full map by row in one of the lists, then uses that for lookup when merging by iterating through the other map. 这将在其中一个列表中按行创建mergeColumn键到完整地图的映射,然后在通过迭代其他映射进行合并时将其用于查找。

static List<Map<String, String>> merge(List<Map<String, String>> left, 
       List<Map<String, String>> right, String joinColumnTableLeft,
       String joinColumnTableRight) {

    Map<String, Map<String, String>> rightById = right.stream()
            .collect(Collectors.toMap(m -> m.get(joinColumnTableRight), 
                                      Function.identity()));

    return left.stream()
               .filter(e -> rightById.containsKey(e.get(joinColumnTableLeft)))
               .map(l -> {
                 Map<String, String> all = new HashMap<>();
                 all.putAll(l);
                 all.putAll(rightById.get(l.get(joinColumnTableLeft)));

                 return all;
               })
               .collect(Collectors.toList());
}

As a test: 作为测试:

Map<String, String> left1 = new HashMap<>(), right1 = new HashMap<>();
left1.put("a", "A");
left1.put("b", "B");
left1.put("c", "C");

right1.put("a", "A");
right1.put("d", "B");

Map<String, String> left2 = new HashMap<>(), right2 = new HashMap<>();
left2.put("a", "AA");
left2.put("b", "BB");
left2.put("c", "CC");

right2.put("a", "AA");
right2.put("d", "BB");

System.out.println(merge(Arrays.asList(left1, left2), 
        Arrays.asList(right1, right2), "a", "a"));

The output is: [{a=A, b=B, c=C, d=B}, {a=AA, b=BB, c=CC, d=BB}] 输出为: [{a=A, b=B, c=C, d=B}, {a=AA, b=BB, c=CC, d=BB}]

The order of entries isn't important, though. 但是,条目的顺序并不重要。 Just note that this assumes that there are no overlapping keys other than the join column. 请注意,这假设除了连接列之外没有重叠键。 Otherwise, you may want to collect pairs of maps instead of calling putAll on a new map. 否则,您可能希望收集地图对,而不是在新地图上调用putAll


The following will support duplicate join keys (and will produce a cartesian product for all entries per key): 以下内容将支持重复的连接键(并将为每个键生成所有条目的笛卡尔积):

static List<Map<String, String>> merge(List<Map<String, String>> left, 
        List<Map<String, String>> right,
        String joinColumnTableLeft, String joinColumnTableRight) {

    Map<String, List<Map<String, String>>> rightById = right.stream()
            .collect(Collectors.groupingBy(m -> m.get(joinColumnTableRight)));

    return left.stream()
            .filter(e -> rightById.containsKey(e.get(joinColumnTableLeft)))
            .flatMap(l -> rightById.get(l.get(joinColumnTableLeft)).stream()
                    .map(r -> {
                                Map<String, String> all = new HashMap<>();
                                all.putAll(l);
                                all.putAll(r);

                                return all;
                            }
                    )
    ).collect(Collectors.toList());
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM