使用Java 8简化循环

时间:2017-03-02 10:44:28

标签: java foreach java-8

我有一个方法可以将地图添加到缓存中,我想知道如何使用Java 8简化此循环。

到目前为止我做了什么:
标准循环我们都知道:

for(int i = 0; i < catalogNames.size(); i++){
    List<GenericCatalog> list = DummyData.getCatalog(catalogNames.get(i));
    Map<String, GenericCatalog> map = new LinkedHashMap<>();
    for(GenericCatalog item : list){
        map.put(item.name.get(), item);
    }
    catalogCache.put(catalogNames.get(i), map);};

使用forEach的第二次迭代:

catalogNames.forEach(e -> {
    Map<String, GenericCatalog> map = new LinkedHashMap<>();
    DummyData.getCatalog(e).forEach(d -> {
        map.put(d.name.get(), d);
    });
    catalogCache.put(e, map);});

第三次迭代,删除不必要的护腕:

catalogNames.forEach(objName -> {
    Map<String, GenericCatalog> map = new LinkedHashMap<>();
    DummyData.getCatalog(objName).forEach(obj -> map.put(obj.name.get(), obj));
    catalogCache.put(objName, map);});

我现在的问题是如何进一步简化这个?
我明白在这一点上用这种方法做其他事情并不是真的有必要,但是,我对这些可能性感到好奇。

2 个答案:

答案 0 :(得分:2)

解决方案2和3存在小问题,可能会导致side effects

  

流行动的行为参数的副作用是,   一般而言,气馁,因为他们经常会导致不知情的违规行为   无国籍要求,以及其他线程安全   危险。

     

作为如何转换流管道的示例   不恰当地使用副作用而不是以下的副作用   代码搜索匹配给定常规字符串的字符串流   表达式,并将匹配放在列表中。

forEach

因此,不要使用HashMap填充Collectors.toMap(..),最好使用List。我对您的数据结构并不是100%肯定,但我希望它足够接近。

有一个Map和相应的List<Integer> ints = Arrays.asList(1,2,3); Map<Integer,List<Double>> catalog = new HashMap<>(); catalog.put(1,Arrays.asList(1.1,2.2,3.3,4.4)); catalog.put(2,Arrays.asList(1.1,2.2,3.3)); catalog.put(3,Arrays.asList(1.1,2.2));

Map

现在我们想要一个新的key,其中地图List是原始map value的元素,而Map是另一个Map's本身。嵌套的catalog键是List value的转换元素,ListMap<Integer, Map<Integer, Double>> result = ints.stream().collect( Collectors.toMap( el -> el, el -> catalog.get(el).stream(). collect(Collectors.toMap( c -> c.intValue(), c -> c )) ) ); System.out.println(result); // {1={1=1.1, 2=2.2, 3=3.3, 4=4.4}, 2={1=1.1, 2=2.2, 3=3.3}, 3={1=1.1, 2=2.2}} 元素本身。疯狂的描述和下面更疯狂的代码:

$baseurl=$block->getUrl();

我希望这会有所帮助。

答案 1 :(得分:0)

如何使用流API中的收集器?具体而言,Collectors#toMap

Map<String, Map<String, GenericCatalog>> cache = catalogNames.stream().collect(Collectors.toMap(Function.identity(),
    name -> DummyData.getCatalog(name).stream().collect(Collectors.toMap(t -> t.name.get(), Function.identity(),
            //these two lines only needed if HashMap can't be used
            (o, t) -> /* merge function */,
            LinkedHashMap::new));

这可以避免改变现有的集合,并为您提供您自己的地图副本(可用于更新缓存或任何您想要的内容)。

另外,我不同意在一行代码的末尾任意添加结束括号 - 大多数样式指南也会反对这一点,因为它有点扰乱了大多数读者的代码流。