【问题标题】:Create Hashmap using string array as value and Enum as Key in Java 8 Lambda-Stream在 Java 8 Lambda-Stream 中使用字符串数组作为值和枚举作为键创建 Hashmap
【发布时间】:2015-10-30 05:48:20
【问题描述】:

我正在尝试使用 Java 8 中的 Lambda-Stream 实现以下逻辑。(请参见下面的示例方法)。我以旧的方式把逻辑放在下面,这样可以很容易地创建解决方案,而不是我的 Lambda 版本 - 流设置更复杂且错误,因为没有得到最终结果。

public static HashMap<EnumObj,String> getHashMapData(String…args){
     int i = 0;
     HashMap<EnumObj,String> hashObj = new HashMap<EnumObj,String>();
     if(args.length <= 6){
           for(String arg : args){
                if(i == 0){
                     hashObj.put(EnumObj.FIRSTNAME,args[i]);
                }else if(i == 1){
                     hashObj.put(EnumObj.LASTNAME,args[i]);
                }else if{……….
                ………….
                }else if(i == 4 && args.length < 5){
                      hashObj.put(EnumObj.COMPANY,args[i]);
                      hashObj.put(EnumObj.COMANYBOSS,args[i+1]);
                }else if(i == 5 && args.length < 6){
                      hashObj.put(EnumObj.COMANYBOSS,args[i]);
                }
           }  
     }
}

如果之前失去了这种循环逻辑,请忽略 if / else 的任何循环逻辑。虽然我一直在尝试我的逻辑,但如果其他人已经成功完成或有建议以最简单的方式实现它,我必须了解一下。

到目前为止,我使用两个Stream 来实现Collections.toMap 选项来创建新地图。但它有 Stream with in a stream 并且更复杂。

如果我自己找到了解决方案,那么将发布该答案,否则将投票选出最佳解决方案。

【问题讨论】:

  • 有点难以分辨你在做什么。在上面的代码中,i 始终为 0,因为您从不修改它。如果在循环中添加i++,则条件if (i == 4 &amp;&amp; args.length &lt; 5)if (i == 5 &amp;&amp; args.length &lt; 6) 将始终为false。
  • 无论如何,我认为你想要的是并行处理两个流,其中一个来自数组{EnumObj.FIRSTNAMEEnumObj.LASTNAME, ...},另一个来自来自args。但是,快速搜索似乎表明 Java 没有提供并行处理两个流的内置方法(请参阅stackoverflow.com/questions/24059837/…)。所以我认为你不会得到一个使用流的好的解决方案。
  • 无论以哪种方式编写,该代码看起来都很糟糕。与其无缘无故地尝试将其转换为 lambda 流,不如尝试修复您的逻辑。看起来您正在尝试解析可变长度数据,但您的解决方案看起来非常脆弱。
  • 阅读标题时我首先想到的是,当知道密钥是enum 时,使用HashMap 的要求从何而来。是因为,您认为每个Map 都必须是HashMap?使用EnumMap 排除了什么?
  • 伙计们...我已将我的 lambda 转换为更通用的东西。我在评论中提到,我很久没有像使用 i 和 for 循环这样的编程了。我这样做是为了以理解的方式提出问题。如果您感到脆弱(我同意),请道歉。这只是为了理解逻辑以实现最终结果。希望这能解释我的观点

标签: java lambda java-8 java-stream


【解决方案1】:

正如 cmets 中已经说过的,此代码不正确。我假设您有一个可变长度的参数数组,并且每个参数对应于 EnumObj 的枚举常量。

如果是这样,你只需要一个简单的 for 循环:

Map<EnumObj, String> result = new HashMap<>();
EnumObj[] enums = EnumObj.values();
for (int i = 0; i < args.length; i++) {
    result.put(enums[i], args[i]);
}

你可以对流做同样的事情,但你不会得到任何东西,IMO:

Map<EnumObj, String> result = new HashMap<>();
EnumObj[] enums = EnumObj.values();
IntStream.range(0, args.length)
         .forEach(i -> result.put(enums[i], args[i]));

【讨论】:

  • 您假设enum 的内在顺序与args 元素的顺序相匹配。不幸的是,OP 的代码/问题中没有任何东西可以证明这一点。
  • 是的,确实,这些是我的假设。如果 OP 回来并明确表示这不是他想要的,我会很乐意删除我的答案。或者他可以按正确的顺序创建一个枚举常量的数组/列表,然后使用上面的代码。
  • 我只是想确认我的理解,即我没有从 Lambda 获得任何新东西。我的原始代码库与您的第一个选项相似(很明显,由于其中包含关键信息,无法放置确切的代码库)。但它更接近我的解决方案和理解。感谢大家的帮助。
猜你喜欢
  • 2015-06-10
  • 1970-01-01
  • 2020-01-15
  • 2011-10-03
  • 2011-03-27
  • 2023-03-26
  • 2016-01-14
  • 1970-01-01
相关资源
最近更新 更多