2017-03-02 44 views
1

我有增加映射到高速缓存的方法,我想知道我可以做更多来简化这个循环与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);}); 

我现在的问题是可以做些什么来简化这个?
我明白,在这一点上用这种方法做任何事情都没有必要,但是,我对可能性很好奇。

+7

提示:缩短并不总是意味着更简单 –

+0

为什么要简化这一点。我认为你的解决方案#2是构想,你直接理解它的作用。 –

+0

正如我在问题中所说的,我同意解决方案#2和解决方案#3既简单又简单(我在代码atm中使用#2)。我只是好奇还有什么可以做的。 – Brenin

回答

2

没有与解决方案2和3个小问题,他们可能会导致side effects

副作用的行为参数,以流操作是,在 一般,气馁,因为他们往往会导致不知情侵犯 的无状态要求,以及其他线程安全性危害。

作为如何变换流流水线 不当使用的副作用到一个不,以下 代码搜索串的那些匹配给定的正 表达的流,并把该比赛中的示例一个列表。

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

因此,而不是使用forEach填充HashMap最好是使用Collectors.toMap(..)。我不是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其中一个地图key是从原来的Listmap value元素是其他Map本身。嵌套的Map's键是来自catalogListvalue的变换元素是List元素本身。疯狂的描述和更疯狂的代码如下:

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

我希望这有助于。

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

这避免了变异现有集合,并为您提供的地图(你可以用它来更新缓存,或者任何你愿意的话)你自己的个人副本。

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