Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java流,获取对象列表的映射_Java_Java 8_Java Stream - Fatal编程技术网

Java流,获取对象列表的映射

Java流,获取对象列表的映射,java,java-8,java-stream,Java,Java 8,Java Stream,正在尝试使用Java8获取列表的映射。我有一系列预先定义的标题: String[] myStringArray = {"TITLE1", "TITLE2", "TITLE3"}; 以及一些页面对象的列表(list) 如果在页面上找到该数组中的值,我需要创建一个包含预定义数组中键的对象列表的映射。结果应该是: {TITLE1=[page1, page2, page3], TITLE2=[page3, page4, page5]} (假设在页面列表中找不到标题3) 我的代码: Arrays.s

正在尝试使用Java8获取列表的映射。我有一系列预先定义的标题:

String[] myStringArray = {"TITLE1", "TITLE2", "TITLE3"};
以及一些页面对象的列表(
list

如果在页面上找到该数组中的值,我需要创建一个包含预定义数组中键的对象列表的映射。结果应该是:

{TITLE1=[page1, page2, page3], TITLE2=[page3, page4, page5]} 
(假设在页面列表中找不到标题3)

我的代码:

Arrays.stream(myStringArray)
        .map(title -> page
                .stream()
                .filter(p -> isPageContainsTitle(p, title))
                .collect(Collectors.toList()))
        .filter(Objects::nonNull)
        .collect(Collectors.toMap(e->e, Function.identity()));
因此,我从myStringArray获得了列表的映射,其键中有list,而不是value:

{[page1, page2, page3]=[page1, page2, page3], [page3, page4, page5]=[page3, page4, page5]} 

只需确保数组具有唯一的标题,然后使用
收集器。toMap

Map<String, List<String>> result = Arrays.stream(myStringArray)
            .map(title -> new AbstractMap.SimpleEntry<>(title,
                    pages.stream().filter(page -> isPageContainsTitle(page,title)).collect(Collectors.toList())))
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
所以

是且应该是等效的

您真正想要的是平面图:

  Arrays.stream(myStringArray)
                .flatMap(title -> pages
                        .stream()
                        .filter(p -> isPageContainsTitle(p, title))
                        .map( p -> new Tuple(t, p)) 
                 )
                 .collect(Collectors.groupingBy( t -> t._1, t -> t._2));
我们需要flatMap,因为我们可能会返回0、1或多个元组(标题、页面)

这假设您有一个Tuple类,我正在基于Scala的Tuple2建模一个


注意,我还没有测试过这段代码。

我能看到的唯一方法是使用单独的对象将它们映射到一个类型为
String
List
的两元素数组,然后使用这些条目构建映射

Object[]{}
数组将包含标题和列表。这是跨嵌套流保留这两个值的唯一方法

我随后将其转换为创建一个
地图

Map<String, List<String>> result = Arrays.stream(myStringArray)
            .map(title -> new AbstractMap.SimpleEntry<>(title,
                    pages.stream().filter(page -> isPageContainsTitle(page,title)).collect(Collectors.toList())))
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
这不需要修改现有的数据结构

Map Map=Arrays.stream(myStringArray)
.map((字符串标题)->新对象[]{title,
page.stream().filter(
(第p页)->isPageContainsTitle(第p页,标题)).collect(
Collectors.toList())})
.filter(arr->arr[1]!=null)
.collect(Collectors.toMap(arr->(String)arr[0],arr->(List)arr[1]);

最终列表中有一个类型安全警告,但应该可以。下面的代码应该适用于您:

package com.shree.test;

import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class StreamTest {
    public static void main(String[] args) {
        String[] myStringArray = {"TITLE1", "TITLE2", "TITLE3"};
        List<String> pages = new ArrayList<>();
        pages.add("TEXT,TITLE2,TEXT,ONE,TWO");
        pages.add("TEXT,TITLE1,TEXT,ONE,TWO");
        pages.add("TEXT,TITLE2,TEXT,ONE,TWO");
        pages.add("TEXT,TITLE2,TEXT,TITLE3,TWO");
        pages.add("TEXT,TITLE3,TEXT,ONE,TWO");



         Map<Object, Object> titleMap = getTitleMap(myStringArray, pages);

         titleMap.entrySet().forEach(System.out::println);
    }

    private static Map<Object, Object> getTitleMap(String[] myStringArray, List<String> pages) {
        Map<Object, Object> titleMap = Arrays.asList(myStringArray).stream()
            .map(
                    (title)->{
                        return new AbstractMap.SimpleEntry<>(title, pages.stream()
                                .filter((page)->page.contains(title))
                                .collect(Collectors.toList()));
                    }
                )
            .collect(Collectors.toMap(entry->entry.getKey(), entry->entry.getValue()));
        return titleMap;
    }
}
package com.shree.test;
导入java.util.AbstractMap;
导入java.util.ArrayList;
导入java.util.array;
导入java.util.List;
导入java.util.Map;
导入java.util.stream.collector;
公共类流测试{
公共静态void main(字符串[]args){
字符串[]myStringArray={“TITLE1”、“TITLE2”、“TITLE3”};
列表页=新建ArrayList();
添加(“正文,标题2,正文,一,二”);
添加(“正文,标题1,正文,一,二”);
添加(“正文,标题2,正文,一,二”);
添加(“文本,标题2,文本,标题3,两”);
添加(“正文,标题3,正文,一,二”);
Map titleMap=getTitleMap(myStringArray,页);
titleMap.entrySet().forEach(System.out::println);
}
私有静态映射getTitleMap(字符串[]myStringArray,列表页){
Map titleMap=Arrays.asList(myStringArray.stream())
.地图(
(标题)->{
返回新的AbstractMap.SimpleEntry(title,pages.stream()
.filter((页面)->page.contains(标题))
.collect(Collectors.toList());
}
)
.collect(Collectors.toMap(entry->entry.getKey(),entry->entry.getValue());
返回标题图;
}
}

Page是一个String对象,我只能用contains方法(包装在我的ispagecontainstite中)检查它。你能用
Page
显示示例吗?你是如何检查标题的?它就像String Page=“TEXT,title,TEXT,ONE,TWO”和“title”可以是字符串中的任意值一样。page.contains(“TITLE”)我也只需要从arrayOr或者简单地
map result=Arrays.stream(myStringArray).collect(Collectors.toMap(Function.identity(),TITLE->pages.stream().filter(page->isPageContainsTitle(page,TITLE)).Collectors(Collectors.toList())无需
映射
操作。虽然
groupingBy
更改了
isPageContainsTitle
的实现可能会更干净。谢谢@Naman,是的,我同意
groupingBy
将是更干净的解决方案!
  Arrays.stream(myStringArray)
                .flatMap(title -> pages
                        .stream()
                        .filter(p -> isPageContainsTitle(p, title))
                        .map( p -> new Tuple(t, p)) 
                 )
                 .collect(Collectors.groupingBy( t -> t._1, t -> t._2));
package com.shree.test;

import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class StreamTest {
    public static void main(String[] args) {
        String[] myStringArray = {"TITLE1", "TITLE2", "TITLE3"};
        List<String> pages = new ArrayList<>();
        pages.add("TEXT,TITLE2,TEXT,ONE,TWO");
        pages.add("TEXT,TITLE1,TEXT,ONE,TWO");
        pages.add("TEXT,TITLE2,TEXT,ONE,TWO");
        pages.add("TEXT,TITLE2,TEXT,TITLE3,TWO");
        pages.add("TEXT,TITLE3,TEXT,ONE,TWO");



         Map<Object, Object> titleMap = getTitleMap(myStringArray, pages);

         titleMap.entrySet().forEach(System.out::println);
    }

    private static Map<Object, Object> getTitleMap(String[] myStringArray, List<String> pages) {
        Map<Object, Object> titleMap = Arrays.asList(myStringArray).stream()
            .map(
                    (title)->{
                        return new AbstractMap.SimpleEntry<>(title, pages.stream()
                                .filter((page)->page.contains(title))
                                .collect(Collectors.toList()));
                    }
                )
            .collect(Collectors.toMap(entry->entry.getKey(), entry->entry.getValue()));
        return titleMap;
    }
}