【问题标题】:Adding elements to a set on creation在创建时将元素添加到集合
【发布时间】:2011-06-03 12:38:52
【问题描述】:

如何在java中创建一个Set,然后在构造的时候给它添加对象。我想做类似的事情:

testCollision(getObject(), new HashSet<MazeState>(){add(thing);});

但这似乎不太对。

【问题讨论】:

    标签: java collections


    【解决方案1】:

    您可以使用com.google.common.collect 中的 util 方法,这是一个相当不错的方法:Sets.newHashSet("your value1", "your valuse2");

    【讨论】:

      【解决方案2】:

      从 Java 9 开始你也可以这样做:

       Set<String> immutableSet = Set.of("value1", "value2");
       Set<Integer> immutableInt = Set.of(1, 2);
      
       List<String> immutableList = List.of("item1", "item2");
      
       Map<String, String> immutableMap = Map.of("key1", "value1", "key2", "value2", "key3", "value3");
      

      请注意,以这种方式创建的任何 Sets/Maps/Lists 都是不可变的(如果我的命名约定没有说服您;)

      【讨论】:

      • 你为什么不是第一个?
      【解决方案3】:

      如果您不介意不变性,那么您可以使用Google Guava's ImmutableSet 类:

      ImmutableSet.of(new MazeState(), new MazeState());
      

      【讨论】:

      • 仅供参考,此方法来自Google Guava库,而非标准JDK。 Guava 有很多非常好的特性值得一试,但如果你想要的只是这个方法,那么请注意你正在导入一个巨大的库。
      【解决方案4】:

      Java 7开始,要实例化一个单元素不可变 Set,你可以使用:

      Collections.singleton(thing);
      

      返回一个只包含指定对象的不可变集合。返回的集合是可序列化的。

      ——Javadoc reference: Collections.singleton(T)


      Java 8 中,您可以使用以下内容实例化包含任意数量对象的 Set,这是对 this answer 的改编:

      Stream.of(thing, thingToo).collect(Collectors.toSet());
      

      【讨论】:

        【解决方案5】:

        你可以使用双括号:

        testCollision(getObject(), new HashSet<MazeState>(){{ add(obj1); add(obj2);}};
        

        或:

        Set<String> set = new HashSet<String>(){{
          add("hello");
          add("goodbye");
        }};
        

        这称为双括号初始化,它是 Java 鲜为人知的特性之一。它的作用是使编译器创建一个匿名内部类,为您创建和操作(因此,例如,如果您的类是最终的,您就不能使用它。)

        现在,话虽如此 - 我鼓励您仅在确实需要简洁的情况下使用它。越明确越好,这样更容易理解您的代码。

        【讨论】:

        • “双括号初始化”并不完全是“功能”:它不是故意引入的。这只是对初始化块和匿名类的巧妙使用。也许太聪明了:)
        • 双大括号初始化也会导致 iiuc 类的子类被创建。这会消耗内存,如果您错误地依赖其他地方的实际类,则会导致意外失败。话虽如此,我在我的测试代码中经常使用双括号初始化,因为它很清楚发生了什么,我不需要担心内存等问题。
        • IntelliJ 的警告补充了上面已经提到的警告 双括号初始化在非静态上下文中使用时会导致内存泄漏,因为创建的匿名类将维护对周围对象的引用。由于需要额外的类加载,它的性能比常规初始化差。如果 equals() 方法不接受子类作为参数,它可能会导致 equals() 比较失败(参见上面的链接)。最后,在 Java 9 之前,它不能与菱形运算符结合使用,因为它不能与匿名类一起使用。
        【解决方案6】:

        其他答案是正确的,但想再添加一种方式。使用initializer block

        new HashSet<MazeState>() {
        
                    {
                        add(new MazeState());
                        add(new MazeState());
                    }
                };
        

        【讨论】:

          【解决方案7】:

          在 Java 5 中

          new HashSet<MazeState>(Arrays.asList(thing));
          

          Arrays.asList(thing) 将您的 thing 转换为一个元素的列表,并从该列表中创建集合。

          供参考:
          http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html#asList(T...)

          【讨论】:

          • 也可以考虑使用Collections.singletonList method
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-12-18
          • 1970-01-01
          相关资源
          最近更新 更多