【问题标题】:Java 8 - How to create Iterable from List<T> and new T without creating temporary variable?Java 8 - 如何在不创建临时变量的情况下从 List<T> 和 new T 创建 Iterable?
【发布时间】:2019-12-09 16:42:36
【问题描述】:

是否可以在不创建临时变量ms 的情况下放置Iterable&lt;? extends Module&gt; modules 并添加新元素?

List<Module> ms = new ArrayList<>(super.superModules);
ms.add(new newModule());
Injector injector = Guice.createInjector(super.stage, ms);

在父母中:

protected List<Module> superModules= new ArrayList<>(Arrays.asList(CucumberModules.createScenarioModule(), new aaaModule(), new bbbModule(), new cccModule()));

我调用的方法:

public static Injector createInjector(Stage stage, Iterable<? extends Module> modules) {
    return new InternalInjectorCreator().stage(stage).addModules(modules).build();
}

【问题讨论】:

  • @VGR,不,他会想念new newModule()

标签: java arrays collections


【解决方案1】:

由于createInjector 方法不需要List,因此您不需要构造List。你可以使用

Injector injector = Guice.createInjector(super.stage, () ->
    Stream.concat(super.superModules.stream(), Stream.of(new NewModule())).iterator());

Iterable 是一个函数式接口,因为它唯一的抽象方法是iterator(),可以通过按需提供Iterator 的函数来实现。

有 3rd 方库提供 Iterator 组合,因此您可以将 super.superModules.iterator()new NewModule() 组合为另一个元素。使用内置设施,我们可以构造一个连接流并将其转换为迭代器。这仍然避免为组合集合分配新的存储空间。

【讨论】:

    【解决方案2】:

    拥有一个名为“superModules”的可变列表听起来是个坏主意;我认为您不希望任何其他代码能够修改此列表,不是吗?

    假设你有 java11+,你可以写:protected final List&lt;Module&gt; superModules = List.of(CucumberModules.createScenarioModule(), ...);

    然后,我了解到您想创建一个新列表,其中包含该列表中的所有元素 + 一个其他元素。不,没有简单的单行代码来混合列表和元素。

    我强烈建议您不要使用一些技巧。例如:

    Stream.of(super.superModules, List.of(new NewModule()).flatMap(List::stream).collect(Collectors.toList());
    

    这些只是用来混淆你想要做的事情。为了便于阅读,我什至不会将以上内容放在一行中。

    Java 8:

    Injector injector = Guice.createInjector(super.stage, () ->
                        Stream.concat(super.superModules.stream(), Stream.of(new NewModule()))
                        .iterator());
    

    【讨论】:

    • @sgrillon 如果您需要传统的 java 答案,您应该将其添加到只有 java 8 的东西才能做的问题和标题中
    • @sgrillon 对于 Java 8,删除包装 Arrays.asList(…)new ArrayList&lt;&gt;( … ) 并考虑将其包装在 Collections.unmodifiableList(…) 中。
    • @rzwitserloot 您的流示例不是 hack。我更喜欢使用Stream.concat(super.superModules.stream(), Stream.of(new NewModule())) …,但是,您的流示例既不错误也不骇人听闻。
    • @Holger 这绝对是一个难以理解的混乱。当您看到这一点时,您不会立即想到:哦,好吧,这是从现有列表 + 一个元素中创建一个新列表。 “可读性”在旁观者的眼中。也许在你看来是这样。我不认为 stackoverflow 评论是讨论 Joe Q. 普通程序员会看到什么的有用场所。
    • 当你认为一段代码没有表达它的意图时,你可以把它放到一个可重用的方法中,并给它一个有意义的名字,例如listPlusOneElement。但无论您是否认为它可读,使用 API 的预期方式都不是 hack。
    【解决方案3】:

    你可以做 Arrays.asList(module1, module2, module3)

    【讨论】:

    • 不,Arrays.asList(module1, module2, module3) 是第一部分,但他会错过new newModule()
    猜你喜欢
    • 1970-01-01
    • 2019-07-01
    • 2012-01-11
    • 1970-01-01
    • 2012-06-16
    • 2021-08-23
    • 1970-01-01
    • 2013-03-01
    • 1970-01-01
    相关资源
    最近更新 更多