Java:一个构造函数或方法将接受数组或集合或列表或...?

发布于 2024-09-08 23:05:50 字数 699 浏览 2 评论 0原文

在Java中是否有一个构造函数可以接受数组或集合?我已经摆弄这个有一段时间了,但我认为这是不可能的。

我希望能够初始化 MyClass,如下所示:

MyClass c = new MyClass({"rat", "Dog", "Cat"});

如下所示:

LinkedList <String> l = new <String> LinkedList();
l.add("dog");
l.add("cat");
l.add("rat");
MyClass c = new MyClass(l);

这就是 MyClass 的样子。我可以将 XXX 设置为什么才能使其正常工作?我知道我可以重载构造函数,但如果我可以最小化代码那就太棒了,对吧?

public class MyClass{

   private LinkedHashSet <String> myList;

   public MyClass(XXX <String> input){
       myList = new LinkedHashSet <String> ();
       for(String s : input){
           myList.put(s);
       }

   }

}

In Java is there anyway to have one constructor that will accept an array or a collection? I have been fiddling with this for a while but I don't think it is possible.

I would like to be able to initialize MyClass, like this:

MyClass c = new MyClass({"rat", "Dog", "Cat"});

And like this:

LinkedList <String> l = new <String> LinkedList();
l.add("dog");
l.add("cat");
l.add("rat");
MyClass c = new MyClass(l);

This is what MyClass looks like. What can I make XXX be so that this will work? I know that I could overload the constructor, but if I can minimize code that would be awesome right?

public class MyClass{

   private LinkedHashSet <String> myList;

   public MyClass(XXX <String> input){
       myList = new LinkedHashSet <String> ();
       for(String s : input){
           myList.put(s);
       }

   }

}

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

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

发布评论

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

评论(5

单身狗的梦 2024-09-15 23:05:50

您可以声明两个构造函数并从第一个构造函数调用第二个构造函数:

class MyClass {
    public MyClass(String... x) {
        // for arrays
        // this constructor delegate call to the second one
        this(Arrays.asList(x));
    }
    public MyClass(List<String> x) {
        // for lists
        // all logic here
    }
}

调用看起来像

new MyClass(new ArrayList<String>());
new MyClass("dog", "cat", "rat");
new MyClass(new String[] {"rat", "Dog", "Cat"});

由于第一个构造函数中只有一行代码,因此它非常简约。

You can declare two constructors and call second from first:

class MyClass {
    public MyClass(String... x) {
        // for arrays
        // this constructor delegate call to the second one
        this(Arrays.asList(x));
    }
    public MyClass(List<String> x) {
        // for lists
        // all logic here
    }
}

Calls would look like

new MyClass(new ArrayList<String>());
new MyClass("dog", "cat", "rat");
new MyClass(new String[] {"rat", "Dog", "Cat"});

Since there's only one line of code in the first constructor, it's pretty minimalistic.

烟酉 2024-09-15 23:05:50

公共类 MyClass1 {

    public MyClass1(final String... animals) {
        for (final String animal : animals) {
            System.out.println("eat " + animal);
        }
    }

    public static void main(final String[] args) {
        new MyClass1();
        new MyClass1("dog", "cat", "rat");
        new MyClass1(new String[] { "dog", "cat", "rat" });
    }
}

public class MyClass2 {

    public MyClass2(final Iterable<String> animals) {
        for (final String animal : animals) {
            System.out.println("eat " + animal);
        }
    }

    public static void main(final String[] args) {
        new MyClass2(Arrays.asList("cat", "rat", "dog", "horse"));
        final LinkedList<String> animals = new LinkedList<String>();
        animals.add("dog");
        animals.add("house");
        animals.addAll(Arrays.asList("cat", "rat"));
        new MyClass2(animals);
    }
}

public class MyClass1 {

    public MyClass1(final String... animals) {
        for (final String animal : animals) {
            System.out.println("eat " + animal);
        }
    }

    public static void main(final String[] args) {
        new MyClass1();
        new MyClass1("dog", "cat", "rat");
        new MyClass1(new String[] { "dog", "cat", "rat" });
    }
}

or

public class MyClass2 {

    public MyClass2(final Iterable<String> animals) {
        for (final String animal : animals) {
            System.out.println("eat " + animal);
        }
    }

    public static void main(final String[] args) {
        new MyClass2(Arrays.asList("cat", "rat", "dog", "horse"));
        final LinkedList<String> animals = new LinkedList<String>();
        animals.add("dog");
        animals.add("house");
        animals.addAll(Arrays.asList("cat", "rat"));
        new MyClass2(animals);
    }
}
不喜欢何必死缠烂打 2024-09-15 23:05:50

看来数组是不可迭代的,所以没有办法做到这一点。不可能有一个接受数组和其他可迭代对象的构造函数。这特别烦人,因为我们可以这样做:

Foo[] foos = ...
for (Foo foo : foos)

请参阅这篇文章了解更多详细信息:为什么数组不能分配给 Iterable?

It appears that arrays are not iterable so there is no way to do this. It is impossible to have one constructor that accepts arrays AND other iterables. This is especially annoying since we can do this:

Foo[] foos = ...
for (Foo foo : foos)

See this post for more details: Why is an array not assignable to Iterable?

不知所踪 2024-09-15 23:05:50

理论上,您可以像这样声明构造函数:

MyClass(Object args) {
    if (args instanceof List) {
        ...
    } else if (args instanceof Set) {
        ...
    } else if (args.getClass().isArray()) {
        ...
    } else {
        thrown new IllegalArgumentException("arg's type is wrong");
    }
}

但在我看来,这将是一个糟糕的 API 设计,因为它将所有类型检查都转移到运行时。 (没有其他方法可以使用单个构造函数来完成此操作。数组类型和 Collection 接口的唯一公共超类型是 Object。)

使用构造函数要好得多如其他答案中所述的重载。

顺便说一句,以下内容(来自您的示例)是 Java 语法错误,无论构造函数声明的参数类型如何:

MyClass c = new MyClass({"rat", "Dog", "Cat"});

这种形式的数组初始值设定项只能在变量声明中使用;例如

String[] foo = {"rat", "Dog", "Cat"};

作为数组创建表达式的一部分;例如

String[] foo = new String[]{"rat", "Dog", "Cat"};
String[][] bar = new String[][]{{"rat", "Dog", "Cat"}, /* ... */};

In theory, you could declare the constructor something like this:

MyClass(Object args) {
    if (args instanceof List) {
        ...
    } else if (args instanceof Set) {
        ...
    } else if (args.getClass().isArray()) {
        ...
    } else {
        thrown new IllegalArgumentException("arg's type is wrong");
    }
}

but IMO, that would be a bad API design as it punts all type checking to runtime. (There is no other way to do this with a single constructor. The only common supertype of array types and the Collection interface is Object.)

It is far better to use constructor overloading as described in the other answers.

Incidentally, the following (from your example) is a Java syntax error, irrespective of the constructor's declared argument types:

MyClass c = new MyClass({"rat", "Dog", "Cat"});

That form of array initializer can only be used in a variable declaration; e.g.

String[] foo = {"rat", "Dog", "Cat"};

or as part of an array creation expression; e.g.

String[] foo = new String[]{"rat", "Dog", "Cat"};
String[][] bar = new String[][]{{"rat", "Dog", "Cat"}, /* ... */};
屌丝范 2024-09-15 23:05:50

如果你确实想要一个构造函数,你可以使用 Arrays.asList ,然后让构造函数采用一个包含 List 和 Set 的 Collection 。

我个人会有两个构造函数。

If you really want a single constructor you could use Arrays.asList and then have the constructor take a Collection which covers List and Set.

I personally would have two constructors.

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