【问题标题】:Java: One constructor or method that will accept array or set or list or ...?Java:一种将接受数组或集合或列表或...的构造函数或方法?
【发布时间】:2011-03-14 09:06:44
【问题描述】:

在 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);
       }

   }

}

【问题讨论】:

    标签: java list collections arrays constructor


    【解决方案1】:

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

    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"});
    

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

    【讨论】:

    • 不错的一个。我可能会反过来做,因为从List&lt;String&gt; 中获取String[] 比基于String[] 构建List&lt;String&gt; 成本更低。
    • BalusC - 你错了。 Arrays.asList(..) 返回与不可变列表相同的数组的视图。几乎没有成本。另一方面,转到 String[] 需要将所有引用复制到新分配的数组
    • @usersmarvin:感谢您的提醒!顺便说一句,要在不是他们自己的问题/答案中通知用户有关 cmets 的信息,请在昵称前加上 @,例如@BalusC。至少需要名称中的前 3 个字符才能找到匹配项。
    【解决方案2】:

    公共类 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);
        }
    }
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

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

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

        查看这篇文章了解更多详情:Why is an array not assignable to Iterable?

        【讨论】:

          【解决方案5】:

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

          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");
              }
          }
          

          但是 IMO,这将是一个糟糕的 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"}, /* ... */};
          

          【讨论】:

            猜你喜欢
            • 2012-11-28
            • 1970-01-01
            • 2013-10-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-06-18
            • 1970-01-01
            • 2011-02-15
            相关资源
            最近更新 更多