java - 使用 Java 8 简化循环

标签 java foreach java-8

我有一个将 map 添加到缓存的方法,我想知道我可以做更多的事情来使用 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 和 3 存在小问题,它们可能会导致 side effects

Side-effects in behavioral parameters to stream operations are, in general, discouraged, as they can often lead to unwitting violations of the statelessness requirement, as well as other thread-safety hazards.

As an example of how to transform a stream pipeline that inappropriately uses side-effects to one that does not, the following code searches a stream of strings for those matching a given regular expression, and puts the matches in a list.

ArrayList<String> results = new ArrayList<>();
 stream.filter(s -> pattern.matcher(s).matches())
       .forEach(s -> results.add(s));  // Unnecessary use of side-effects!

因此,最好使用 Collectors.toMap(..),而不是使用 forEach 来填充 HashMap。我对你的数据结构不是100%确定,但我希望它足够接近。

有一个List和相应的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,其中 map key是原始List中的元素,map value 是另一个 Map 本身。嵌套的 Map 的 键是来自 catalog List 的转换元素,valueList元素本身。下面是疯狂的描述和更疯狂的代码:

Map<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}}

我希望这会有所帮助。

关于java - 使用 Java 8 简化循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42553191/

相关文章:

java - 在不同的Android Activity中解析打开推送通知

java - web.xml 自定义错误页面不工作

php - 如何使用 foreach 循环根据所选选项将数据检索到文本区域?

javascript - JQuery 动态输入字段功能不适用于 php foreach?

java - Java8 中将 arraylist 嵌套到 hashmap

java - 如何在 Swing 应用程序中停止计时器

swift - 使用 ForEach 循环在 Swift 中用不同颜色绘制同心圆

java - 从另一个列表中查找列表中的(自定义)对象

java - 接口(interface)的默认方法存储在内存中的什么位置?

java - 方法 cancel() 和方法 interrupt() 是否做重复工作?