简体   繁体   English

重构Java 8流代码

[英]Refactoring Java 8 stream code

I have implemented the following code using Java 8. 我使用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());

Now. 现在。 I want to know any better way of doing this instead of repeating the same lines of code twice. 我想知道更好的方法,而不是重复相同的代码行两次。

A bigger issue than repeating the same code twice is executing the same code twice. 比重复相同代码两次更大的问题是两次执行相同的代码。

It would be more efficient to run a single Stream pipeline to produce your output : 运行单个Stream管道来生成输出会更有效:

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

This would give you for each value of your original Map (not only the two values your original code is searching for), the joint keys having that value. 这将为您提供原始Map每个值(不仅是原始代码搜索的两个值),具有该值的联合键。

Then you can extract from the Map the data you need : 然后,您可以从Map提取所需的数据:

String newCoName = keysByValue.get(newcoId);
String oldCoName = keysByValue.get(oldcoId);

Sample input and output : 样本输入和输出:

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

Output : 输出:

ab
cd

Since the whole difference is an id, a simple method does that for you. 由于整个差异是一个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()); 
}

大多数IDE都可以使用“提取方法”重构为您重构: http//refactoring.com/catalog/extractMethod.html或者您可以手动完成

You may use this helper method: 您可以使用此辅助方法:

public static String join(Map<String, String> map, String value) {
    return map.keySet().stream()
            .filter(key -> Objects.equals(map.get(key), value))
            .collect(Collectors.joining());
}

Here some example code using the method: 这里使用该方法的一些示例代码:

    Map<String, String> coMap = new HashMap<>();
    coMap.put("A", null);
    coMap.put("B", "V");
    coMap.put("C", "V");
    coMap.put("D", "Z");
    coMap.put("E", "Z");
    coMap.put("F", null);

    System.out.println("Vs: " + join(coMap, "V"));
    System.out.println("Zs: " + join(coMap, "Z"));

And here the output: 在这里输出:

Vs: BC
Zs: DE

Other way uses with FunctionalInterface Predicate , your condition filter will be dynamic 使用FunctionalInterface Predicate其他方式,您的条件过滤器将是动态的

public static Predicate<Map.Entry> getPredicate(String col) {
    return p -> p.getValue().equals(col);
}

public static String getName(HashMap<String, String> coMap, Predicate<Map.Entry> predicate) {
    return coMap.entrySet()
            .stream()
            .filter(predicate)
            .map(coEntry -> coEntry.getKey())
            .collect(Collectors.joining());
}

Calling in your code: 调用你的代码:

  getName(coMap, getPredicate(newcoId));
  getName(coMap, getPredicate(oldcoId));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM