如何在比较映射和列表时将 Java 7 重构为 Java 8



我想重构以下代码,使其更具可读性。有没有办法使用流和 lambda 使其更具可读性,或者保持代码不变是否有意义?

List<Data> data = ...;
Map<String, Task> tasks = ...;
for (Data datum : data) {
    String compKey = datum.getCompKey();
    for (Map.Entry<String, Task> taskEntry : tasks.entrySet()) {
        String taskKey = taskEntry.getKey();
        Task task = taskEntry.getValue();
        if (taskKey != null && task != null) {
            String subKey = Joiner.on(".").useForNull("null").join(Arrays.copyOfRange(taskKey.split("\."), 0, 3));
            if (compKey.equals(subKey)) {
                task.setVal1(datum.getVal1());
                task.setVal2(datum.getVal2());
                task.setVal3(datum.getVal3());                       
                break;
            }
        }
    }
}

这个怎么样?

tasks.forEach((key, task) -> {
    if (key != null && task != null) {
        key = String.join(".", Arrays.asList(key.split("\.")).subList(0, 3));
        data.stream()
            .filter(d -> d.getCompKey().equals(key))
            .findAny()
            .ifPresent(d -> {
                task.setVal1(d.getVal1());
                task.setVal2(d.getVal2());
                task.setVal3(d.getVal3());
            });
    }
});

我不会说这比你的代码更具可读性,但它表明好的 ol' for 循环仍然足够了:

List<Data> data = ...;
Map<String, Task> tasks = ...;
UnaryOperator<String> function = s -> {
    return Joiner.on(".")
                 .useForNull("null")
                 .join(Arrays.copyOfRange(s.split("\."), 0, 3));
};
data.forEach(datum -> {
    final String compKey = datum.getCompKey();
    tasks.entrySet()
         .stream()
         .filter(e -> e.getKey() != null && e.getValue() != null)
         .filter(e -> compKey.equals(function.apply(e.getKey())))
         .findFirst()
         .map(Map.Entry::getValue)
         .ifPresent(task -> {
             task.setVal1(datum.getVal1());
             task.setVal2(datum.getVal2());
             task.setVal3(datum.getVal3());
         });
});

最新更新