结合 guava 的 ImmutableList 和 varargs

发布于 2024-10-09 07:56:42 字数 547 浏览 1 评论 0原文

我想要创建一个构造函数,它将接受一个或多个整数并将其作为 ImmutableList 保存到字段中。根据 Bloch 的第 42 条“使用 varargs 传递一个或多个参数的正确方法”,我创建了 smt,比如

class Foo{
    private final ImmutableList<Integer> bar;
    public Foo(Integer first, Integer... other) {
        this.bar = ImmutableList.<Integer>builder()
                .add(first)
                .addAll(Arrays.asList(other))
                .build();
    }
}

Why builder does not get genericautomatically?而且,正如它的气味一样。我怎样才能重写它?

更新 泛型问题已解决。任何有关重构的建议都非常有帮助。

I want create constructor that will take one or more integers and save it into field as ImmutableList. According to "The right way to use varargs to pass one or more arguments" by Bloch's Item 42 I create smt like

class Foo{
    private final ImmutableList<Integer> bar;
    public Foo(Integer first, Integer... other) {
        this.bar = ImmutableList.<Integer>builder()
                .add(first)
                .addAll(Arrays.asList(other))
                .build();
    }
}

Why builder doesn't get generic automatically? And, as it smells. How I can rewrite it?

upd
qustion with generics solved. Any suggestions about refactoring are very helpful.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你爱我像她 2024-10-16 07:56:42

因为调用 builder() 时没有表达式的左侧。编译器无法推断要在那里添加什么类型。 (它无法从后续方法调用中推断出它)

如果将其更改为以下内容,它会起作用:

Builder<Integer> builder = ImmutableList.builder();
this.bar = builder.add(first).addAll(Arrays.asList(other)).build();

但是,您可以安全地保留当前代码 - 这很好。甚至比上面的例子更好(它更短)

关于重构 - 为什么不使用 .add(first).add(other)add 方法有一个可变参数版本。

Because the when calling builder() there is no left-hand side of the expression. The compiler cannot infer what type to add there. (It cannot infer it from subsequent method calls)

If you change it to the following, it works:

Builder<Integer> builder = ImmutableList.builder();
this.bar = builder.add(first).addAll(Arrays.asList(other)).build();

However, you can safely retain your current code - it is fine. And even better than the above example (it's shorter)

About the refactoring - why not use .add(first).add(other)? The add method has a varargs version.

靑春怀旧 2024-10-16 07:56:42

关于你的第二个问题(如何重构构造函数以使其更短/更具可读性),我会这样做:

class Foo{
    private final ImmutableList<Integer> bar;
    public Foo(Integer first, Integer... other) {
        this.bar = ImmutableList.copyOf(Lists.asList(first, other));
    }
}

两者 Lists.asList 方法的设计就是为了实现这一目标,根据其 javadoc:

当使用可变参数方法时,这很有用
需要使用诸如 (Foo
firstFoo, Foo...moreFoos),按顺序
以避免过载歧义或
强制执行最小参数计数。

它也比 ImmutableList.Builder 性能更高,因为它避免了在 Builder 内创建临时 ArrayList 或调整其大小。


Regarding your second question (how to refactor you constructor to make it shorter / more readable), I would do this:

class Foo{
    private final ImmutableList<Integer> bar;
    public Foo(Integer first, Integer... other) {
        this.bar = ImmutableList.copyOf(Lists.asList(first, other));
    }
}

Both Lists.asList methods were designed with this goal in mind, according to their javadoc:

This is useful when a varargs method
needs to use a signature such as (Foo
firstFoo, Foo... moreFoos), in order
to avoid overload ambiguity or to
enforce a minimum argument count.

It's also more performant than the ImmutableList.Builder, since it avoids the creation / resizing of a temporary ArrayList inside the Builder.


~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文