代码之家  ›  专栏  ›  技术社区  ›  jhenya-d

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

  •  1
  • jhenya-d  · 技术社区  · 5 年前

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

    String[] myStringArray = {"TITLE1", "TITLE2", "TITLE3"};
    

    List<String> ).

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

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

    我的代码:

    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]} 
    
    2 回复  |  直到 5 年前
        1
  •  3
  •   Naman    5 年前

    只要确保数组有唯一的标题,然后使用 Collectors.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));
    

    正如@Naman建议的那样,你可以避免 map

    Map<String, List<String>> result = Arrays.stream(myStringArray) 
                         .collect(Collectors.toMap(Function.identity() 
                                            ,title -> pages.stream()
                                                           .filter(page -> isPageContainsTitle(page, title))
                                                           .collect(Collectors.toList())));
    
        2
  •  1
  •   Shrirang Kumbhar    5 年前

    下面的代码应该对您有用:

    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;
        }
    }
    
        3
  •  0
  •   tpdi    5 年前

     e->e
    

      Function.identity()
    

    你真正想要的是平面图:

      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));
    

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

        4
  •  0
  •   WJS    5 年前

    我能看到的唯一方法是对单独的对象执行此操作—将它们映射到两个元素的类型数组 String List<Page> 然后使用这些条目来构建映射。

    这个 Object[]{}

    我后来把他们塑造成 Map<String,List<Page>>

    这不需要修改现有的数据结构。

     Map<String, List<Page>> map = Arrays.stream(myStringArray)
                .map((String title) -> new Object[] {title,
                                           page.stream().filter(
                                       (Page p) -> isPageContainsTitle(p, title)).collect(
                                        Collectors.toList())})
                .filter(arr->arr[1] != null)
                .collect(Collectors.toMap(arr -> (String)arr[0], arr -> (List<Page>)arr[1]));
    

    在最终的列表转换中有一个类型安全警告,但应该没有问题。