Java ArrayList和HashMap实时创建

60

有人能提供一个创建Java ArrayListHashMap 的示例吗?而不是通过add()put()方法,而是在类实例化时提供数组/哈希表的初始数据。

为了举例说明,请提供类似于PHP的示例:

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

你是在问如何执行该操作的语法,还是想要一个真实世界的例子来说明为什么你会想要这样做? - Bill the Lizard
8个回答

114
List<String> list = new ArrayList<String>() {
 {
    add("value1");
    add("value2");
 }
};

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

3
这些方法很好。但是内容在创建之后可以进行修改。不可变的方法非常好! - Steve McLeod
9
有时候会有危险。由于匿名内部类会保留对其父对象的引用,因此您将获得对封闭类的引用。这可能会导致垃圾回收和序列化方面的问题。 - Andreas Petersson
5
我非常不喜欢双括号初始化。为什么要创建一个新的(非静态)内部类,当一个简单的初始值设定器同样可以做到呢? - Michael Myers
我一直认为双大括号的方法很好(特别是用于GUI构建)- 但是关于父对象引用的评论非常好。在这里要小心谨慎。最好创建一个小的Map builder类,它接受对象的可变参数(键、值、键值等)。 - Kevin Day
有任何性能问题吗?我的意思是,您每次创建一个扩展ArrayList的匿名类。如果您创建ArrayList实例,然后将项目添加到其中,那么它的性能会更好。或者这些类是在编译后出现的? - degr
如果您按照这种方式创建它,那么它将无法进行序列化! - clankill3r

39
一个不错的方式是使用List.of()(自Java 8起)和 Map.of() (自Java 9起):
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");

2
500kB是为了仅仅做到这一点而付出的高昂代价。如果唯一想要的是在运行时填充集合,那么接受的答案在我看来是最好的。 - Damien B
讨厌这种方法的另一个原因是它是一个不可变列表,虽然我猜测(没有阅读文档)肯定存在可变列表? - cgp
它是按设计不可变的!但是,是的,还有其他选择。如果它是不可变的,你可以轻松地在线程之间共享一个实例,因此也可以在 Web 请求之间共享。500 Kb 是一个高代价。但是在 Google Collections 中有很多其他好东西,这值得付出代价。 - Steve McLeod
@Damien- 很好,但是没有什么能阻止用户编写自己版本的该方法。 - Philip Guin
9
Map.of是Java 9的功能,不是Java 8! - vahid kh

32

数组可以转换为 List

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

6
请注意,Arrays.asList方法返回的是一个固定大小的java.util.Arrays$ArrayList对象,而非java.util.ArrayList对象。请留意此差异。 - user85421

8

对于短列表:

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

不是真的.. 来自 java.util.Arrays.java:public static List asList(T... a) { return new ArrayList<T>(a); } 因此它只返回一个预初始化的ArrayList。 - Andreas Petersson
3
查看源代码。数组有它自己内部的ArrayList类,该类不支持add()或remove()操作。 - Michael Myers
1
从asList的文档中可以得知:"返回由指定数组支持的固定大小列表。" - user85421

7

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

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

同样适用于地图(Map):
Map<String, String> map = new HashMap<String, String>() {{
    put("a", "a");
    put("b", "b");
}};

我认为这是最优雅和易读的方法。

其他方法需要先创建一个数组,然后将其转换为列表 - 在我看来太昂贵,而且不够易读。


5

对于列表,你可以像这样使用 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)创建HashMap存在缺陷


3
你是指像这样吗?
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<? extends E>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)); } - Steve McLeod
(可以利用varags Arrays.asList()简化示例代码; https://dev59.com/c3VC5IYBdhLWcg3wixw0#635078) - Jonik
我正在展示单独的步骤,以便在你已经有一个数组时如何明确做事情。 - Jon Skeet
为什么不使用var-args,这样您就可以传递任意数量的项? - sal

0

这个怎么样?

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

我知道很多答案提供了类似的解决方案,但我认为这个更加精确和简洁。 如果你有很多值,你可能想这样做:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接