2017-03-02 73 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)); 

這避免了變異現有集合,併爲您提供的地圖(你可以用它來更新緩存,或者任何你願意的話)你自己的個人副本。

此外,我會不同意在代碼行的末尾任意放置尾括號 - 大多數樣式指南也會反對這一點,因爲它有點干擾了大多數讀者的代碼流。