【问题标题】:Java ArrayList and HashMap on-the-fly即时 Java ArrayList 和 HashMap
【发布时间】:2009-05-12 13:33:07
【问题描述】:

有人可以提供一个即时创建 Java ArrayListHashMap 的示例吗?因此,与其做add()put(),不如在类实例化时实际为数组/哈希提供种子数据?

举个例子,类似于 PHP 的例子:

$array = array (3, 1, 2);
$assoc_array = array( 'key' => 'value' );

【问题讨论】:

  • 您是在询问有关如何执行此操作的语法,还是您想要的真实示例?

标签: java collections


【解决方案1】:
List<String> list = new ArrayList<String>() {
 {
    add("value1");
    add("value2");
 }
};

Map<String,String> map = new HashMap<String,String>() {
 {
    put("key1", "value1");
    put("key2", "value2");
 }
};

【讨论】:

  • 这些方法很好。但创建后可以修改内容。不可变的方法太棒了!
  • 这有时很危险。您将获得对封闭类的引用,因为匿名内部类维护对其父对象的引用。这可能会导致垃圾收集和序列化问题。
  • 我根本不喜欢双括号初始化。为什么要创建一个新的(非静态)内部类,而一个简单的初始化器也可以做到这一点?
  • 我一直认为双括号方法很好(尤其是用于 GUI 构造)——但是对父对象引用的注释做得很好。在这里谨慎行事。组成一个接受可变参数对象(键、值、键值等)的小型 Map builder 类可能会更好。
  • 是否存在性能问题?我的意思是,您每次创建一个匿名类,它扩展 ArrayList。如果您将创建 arraylist 实例,而不是向其中添加项目,那么认为它对性能会更酷。还是编译后出现这个类?
【解决方案2】:

一个很好的方法是使用List.of()Map.of()(从Java 8 开始):

List<String> list = List.of("A", "B", "C");
    
Map<Integer, String> map = Map.of(1, "A",
                                  2, "B",
                                  3, "C");

Java 7 及更早版本可以使用Google Collections:

List<String> list = ImmutableList.of("A", "B", "C");

Map<Integer, String> map = ImmutableMap.of(
  1, "A",
  2, "B",
  3, "C");

【讨论】:

  • 500kB 是为了做到这一点而付出的高昂代价。如果唯一想要的就是动态填写集合,那么接受的答案是恕我直言最好的。
  • 不喜欢这种方法的另一个原因是它是一个不可变列表,尽管我猜测(没有阅读文档)有一个可变列表?
  • 它在设计上是不可变的!但是,是的,还有其他选择。如果它是不可变的,您可以轻松地在线程之间共享一个实例,从而在 Web 请求之间共享。 500 Kb 是一个高昂的代价。但 Google 收藏中还有很多其他好东西,值得付出代价。
  • @Damien- 很公平,但没有什么能阻止用户编写自己的此方法版本。
  • Map.of 是 Java 9 功能而不是 8!
【解决方案3】:

数组可以转换为Lists:

List<String> al = Arrays.asList("vote", "for", "me"); //pandering

请注意,这不是返回一个ArrayList,而是一个任意的List实例(在这种情况下它是一个Array.ArrayList)!

Bruno 的方法效果最好,可以在地图上即时考虑。我更喜欢列表的另一种方法(见上文):

Map<String,String> map = new HashMap<String,String>() {
 {
    put("key1", "value1");
    put("key2", "value2");
 }
};

【讨论】:

  • 被警告,Arrays.asList 不返回 java.util.ArrayList 而是一个固定大小的 java.util.Arrays$ArrayList!
【解决方案4】:

短名单:

    List<String> ab = Arrays.asList("a","b");

【讨论】:

  • 不是真的.. from java.util.Arrays.java: public static List asList(T... a) { return new ArrayList(a); } 所以它只返回一个预初始化的 ArrayList
  • 进一步查看源代码。 Arrays 有自己的内部 ArrayList 类,不支持 add() 或 remove()。
  • 并从 asList 的文档中:“返回由指定数组支持的固定大小的列表。”
【解决方案5】:

使用一个不错的匿名初始化器:

List<String> list = new ArrayList<String>() {{
    add("a");
    add("b");
}};

地图也是如此:

Map<String, String> map = new HashMap<String, String>() {{
    put("a", "a");
    put("b", "b");
}};

我觉得这是最优雅和可读的。

其他方法需要先创建一个数组,然后将其转换为一个列表——在我看来太贵了,而且可读性也差。

【讨论】:

    【解决方案6】:

    对于列表,您可以像这样使用Arrays.asList

    List<String> stringList = Arrays.asList("one", "two");
    List<Integer> intList = Arrays.asList(1, 2);
    

    对于地图,你可以使用这个:

    public static <K, V> Map<K, V> mapOf(Object... keyValues) {
        Map<K, V> map = new HashMap<>();
    
        K key = null;
        for (int index = 0; index < keyValues.length; index++) {
            if (index % 2 == 0) {
                key = (K)keyValues[index];
            }
            else {
                map.put(key, (V)keyValues[index]);
            }
        }
    
        return map;
    }
    
    Map<Integer, String> map1 = mapOf(1, "value1", 2, "value2");
    Map<String, String> map2 = mapOf("key1", "value1", "key2", "value2");
    

    注意:在Java 9 中你可以使用Map.of
    注意2:Double Brace Initialization 用于按照其他答案中的建议创建 HashMaps caveats

    【讨论】:

      【解决方案7】:

      你的意思是这样的?

      public List<String> buildList(String first, String second)
      {
           List<String> ret = new ArrayList<String>();
           ret.add(first);
           ret.add(second);
           return ret;
      }
      
      ...
      
      List<String> names = buildList("Jon", "Marc");
      

      或者您对采用Collection&lt;? extends E&gt;ArrayList 构造函数感兴趣?例如:

      String[] items = new String[] { "First", "Second", "Third" };
      // Here's one way of creating a List...
      Collection<String> itemCollection = Arrays.asList(items);
      // And here's another
      ArrayList<String> itemList = new ArrayList<String>(itemCollection);
      

      【讨论】:

      • 对 Jon 的建议略有改进:适用于任意数量的项目: public List buildList(String... items) { return new ArrayList(Arrays.asList(items)) ; }
      • (示例代码可以通过使用 varags Arrays.asList() 来简化一点;stackoverflow.com/questions/258954/…)
      • 我展示了单独的步骤,以便在您已经获得数组时清楚地了解如何做事。
      • 为什么不使用 var-args 来传递任意数量的项目?
      【解决方案8】:

      这个怎么样?

      ArrayList<String> array = new ArrayList<String>(Arrays.asList("value1", "value2"));
      

      我知道很多答案都提供了类似的解决方案,但我认为这个更准确、更简洁一些。 如果你有很多价值观,你可能想这样做:

      ArrayList<String> array = new ArrayList<String>(Arrays.asList(
          "value1",
          "value2",
          "value3",
          ...
      ));
      

      【讨论】:

        猜你喜欢
        • 2017-08-30
        • 2011-01-24
        • 2013-11-15
        • 1970-01-01
        • 1970-01-01
        • 2020-05-26
        • 1970-01-01
        • 2011-06-04
        • 2012-03-26
        相关资源
        最近更新 更多