重构Java 8流代码

vij*_*ard 2 java java-8 java-stream

我使用Java 8实现了以下代码.

Map<String, String> coMap = getHashMap();

String newCoName = coMap.entrySet()
                     .stream()
                     .filter(coEntry -> coEntry.getValue().equals(newcoId))
                     .map(coEntry -> coEntry.getKey())
                     .collect(Collectors.joining());


String oldCoName = coMap.entrySet()
                     .stream()
                     .filter(coEntry -> coEntry.getValue().equals(oldcoId))
                     .map(coEntry -> coEntry.getKey())
                     .collect(Collectors.joining());
Run Code Online (Sandbox Code Playgroud)

现在.我想知道更好的方法,而不是重复相同的代码行两次.

Era*_*ran 10

比重复相同代码两次更大的问题是两次执行相同的代码.

运行单个Stream管道来生成输出会更有效:

Map<String,String> keysByValue =
            coMap.entrySet()
                 .stream()
                 .collect(Collectors.groupingBy(Map.Entry::getValue,
                                                Collectors.mapping(Map.Entry::getKey,
                                                                   Collectors.joining())));
Run Code Online (Sandbox Code Playgroud)

这将为您提供原始的每个值Map(不仅是原始代码搜索的两个值),具有该值的联合键.

然后,您可以从Map您需要的数据中提取:

String newCoName = keysByValue.get(newcoId);
String oldCoName = keysByValue.get(oldcoId);
Run Code Online (Sandbox Code Playgroud)

样本输入和输出:

Map<String,String> coMap = new HashMap<> ();
coMap.put("a","foo");
coMap.put("b","foo");
coMap.put("c","bar");
coMap.put("d","bar");
Map<String,String> keysByValue = ... // same as the code above
String newValueKeys = keysByValue.get("foo");
String oldValueKeys = keysByValue.get("bar");
System.out.println (newValueKeys);
System.out.println (oldValueKeys);
Run Code Online (Sandbox Code Playgroud)

输出:

ab
cd
Run Code Online (Sandbox Code Playgroud)

  • 除了`newcoId`和`oldcoId`之外,还不清楚是否还有其他值.如果是这样,只允许这两个值通过的"过滤器"步骤可以避免做不必要的工作.如果我们假设只有两个值(或使用`filter`步骤),我们也可以使用`partitioningBy`而不是`groupingBy`. (3认同)
  • @Holger我认为生成一个包含原始Map的所有值作为键的Map会很有用,但这取决于实际用法 - 即我们是否可以生成一次这个Map并继续将它重新用于不同的值,或者我们必须在每次更新原始地图时生成它. (2认同)

chr*_*con 5

由于整个差异是一个id,一个简单的方法为你做.

String getName(int id) { // supposed id is an integer
    return coMap.entrySet()
             .stream()
             .filter(coEntry -> coEntry.getValue().equals(id))
             .map(coEntry -> coEntry.getKey())
             .collect(Collectors.joining()); 
}
Run Code Online (Sandbox Code Playgroud)