【问题标题】:Java 8 lambda efficient method solutionJava 8 lambda 高效方法解决方案
【发布时间】:2021-01-05 03:46:52
【问题描述】:

我想使用 java 8 更有效、更清晰地改进代码。谁能告诉我,非常感谢 我想从生成器的检查中获取 idList 和 nameList 。 代码在下面。

LocalDateTime newStart = LocalDateTime.now();
List<Check> checks = generateCheck();
List<String> idListNew = new ArrayList<>();
List<String> nameListNew = new ArrayList<>();
checks.forEach(ck -> {
    idListNew.add(ck.getId());
    nameListNew.add(ck.getName());
});

【问题讨论】:

  • 我猜你已经有了有效的方法
  • 考虑一下迭代一次还是两次作为权衡,newStart 需要什么?
  • 我认为你的意思是高效,我们的代码已经有效。
  • 使用List&lt;String&gt; idListNew = new ArrayList&lt;&gt;(checks.size()); List&lt;String&gt; nameListNew = new ArrayList&lt;&gt;(checks.size()); 初始化具有所需容量的列表。除此之外,没有机会提高性能。
  • 非常感谢

标签: java spring java-8 java-stream


【解决方案1】:

您还可以组合消费者,例如:

Consumer<Check> idConsumer = ck -> idListNew.add(Check::getId);
Consumer<Check> nameConsumer = ck -> idListNew.add(Check::getName);

checks.stream().forEach(idConsumer.andThen(nameConsumer));

【讨论】:

  • 感谢您帮助我更好地了解消费者。
【解决方案2】:

基于 Java 8 Streams 和 Lambda 的解决方案,没有副作用。

LocalDateTime newStart = LocalDateTime.now();
List<Check> checks = generateCheck();
List<String> idListNew = checks.stream().map(Check::getId).collect(Collectors.toList());
List<String> nameListNew = checks.stream().map(Check::getName).collect(Collectors.toList());

【讨论】:

  • 是考虑原方案性能的有效方式
  • @janith1024 我觉得这在性能上确实更好,因为t涉及到流,而且还提供了额外的灵活性。
  • 迭代两次我慢慢测试它
  • 虽然这个解决方案可能效果不佳,但我非常感谢。
  • @janith1024 原始解决方案会产生副作用,这在使用 Streams 时是一个很大的问题。流并不完全是关于性能的。流允许声明式编程(做什么)而不是命令式编程(如何做)。简单的 for 循环比流快得多,但是在编写循环逻辑时可能会犯很多错误(您可以使用 int i = 1 启动 for 循环,并在您真的想从 1 循环到10)。阅读本文了解更多信息shazsterblog.blogspot.com/2014/11/…
【解决方案3】:

如果你碰巧使用 Java 12 或更高版本,那么你可以使用teeing 收集器:

Merger m = checks.stream()
    .collect(teeing(
        mapping(Check::getId, toList()),
        mapping(Check::getName, toList()),
        Merger::new));

System.out.println(m.ids());
System.out.println(m.names());

mapping、teeing 和 toList 是来自 java.util.stream.Collectors 的静态导入。

其中Merger 是以下形式的容器类:

private static record Merger(List<String> ids, List<String> names) { }

// Records are a language feature since Java 15. Otherwise, you could instead
// write this class yourself:
class Merger {
    List<String> ids;
    List<String> names;
    // All-args constructor and getters
}

// Or you could just use an existing type like Map.Entry or Pair.

上述解决方案的优点是它遍历列表一次,否则如果列表非常大,则会造成性能损失。您自己的解决方案在这方面具有相同的优势。

【讨论】:

  • 非常感谢。如果我使用 Java 12,我会试试看。
【解决方案4】:

与上述答案相同,但性能更有效:

LocalDateTime newStart = LocalDateTime.now();
List<Check> checks = generateCheck();
List<String>[] temp = 
                checks.stream().map((e) -> new String[] {e.getId(), e.getName()}).collect(() -> 
                    {
                        List<String>[] arr = 
                                new ArrayList[2];
                        arr[0] = new ArrayList<>();
                        arr[1] = new ArrayList<>();
                        return arr;
                    }
                , (list, e) -> {
                    list[0].add(e[0]);
                    list[1].add(e[1]);
                }, (list, otherList) -> {
                    list[0].addAll(otherList[0]);
                    list[1].addAll(otherList[1]);
                });
List<String> idListNew = temp[0];
List<String> nameListNew = temp[1];

【讨论】:

  • 很抱歉我会告诉你,当我测试它时它会更慢。顺便说一句,非常感谢。
  • 我正在从您的解决方案中学习更多操作。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多