在一行中初始化一个ArrayList

我想创build一个用于testing目的的选项列表。 起初,我这样做了:

ArrayList<String> places = new ArrayList<String>(); places.add("Buenos Aires"); places.add("Córdoba"); places.add("La Plata"); 

然后我重构代码如下:

 ArrayList<String> places = new ArrayList<String>( Arrays.asList("Buenos Aires", "Córdoba", "La Plata")); 

有没有更好的方法来做到这一点?

实际上,初始化ArrayList的“最好”方法可能是你写的方法,因为它不需要以任何方式创build一个新的List

 ArrayList<String> list = new ArrayList<String>(); list.add("A"); list.add("B"); list.add("C"); 

问题在于需要input相当多的内容来引用该list实例。

还有其他的select,比如用一个实例初始化器(也称为“双括号初始化”)创build一个匿名的内部类:

 ArrayList<String> list = new ArrayList<String>() {{ add("A"); add("B"); add("C"); }}; 

然而,我不太喜欢这种方法,因为你最终得到的是一个ArrayList的子类,它有一个实例初始化器,而这个类是为了创build一个对象而创build的 – 这对我来说似乎有点矫枉过正。

如果Project Coin的Collection Literals提案被接受了(它将在Java 7中引入,但它不太可能成为Java 8的一部分)。

 List<String> list = ["A", "B", "C"]; 

不幸的是,它不会帮助你,因为它会初始化一个不可变List而不是一个ArrayList ,此外,它还不可用,如果它将会。

如果你只是把它声明为一个List ,那么它会更简单 – 它是否必须是一个ArrayList?

 List<String> places = Arrays.asList("Buenos Aires", "Córdoba", "La Plata"); 

或者如果你只有一个元素:

 List<String> places = Collections.singletonList("Buenos Aires"); 

这将意味着places不可变的 (试图改变它将导致UnsupportedOperationExceptionexception被抛出)。

要创build一个可变列表,这是一个具体的ArrayList你可以从不可变列表创build一个ArrayList

 ArrayList<String> places = new ArrayList<>(Arrays.asList("Buenos Aires", "Córdoba", "La Plata")); 

简单的答案

在Java 8或更早版本中:

 List<String> strings = Arrays.asList("foo", "bar", "baz"); 

这会给你一个由数组支持的List ,所以它不能改变长度,但你可以调用List.set()


在Java 9中:

 List<String> strings = List.of("foo", "bar", "baz"); 

这将给你一个不变的List ,所以它不能改变。 无论如何,在大多数情况下,你预先填充它是很好的。


较短的答案

静态导入可以使其更短:

 List<String> strings = asList("foo", "bar", "baz"); 

这也需要静态导入:

 import static java.util.Arrays.asList; 

哪个现代IDE将build议并自动为您做。 例如在IntelliJ IDEA中,按下Alt+Enter并selectStatic import method...


我不build议用List.of方法来做这List.of ,因为它变得令人困惑。


如果你真的需要一个ArrayList

引用JEP 269 (强调我的):

有一部分用例用一组预定义的值来初始化可变集合实例。 通常最好将这些预定义的值放在不可变的集合中,然后通过拷贝构造函数初始化可变集合。

如果你必须出于某种原因有一个ArrayList ,例如,如果你需要一个可以改变长度的List ,请使用

 List<String> strings = new ArrayList<>(asList("foo", "bar", "baz")); 

或者在Java 9中:

 List<String> strings = new ArrayList<>(List.of("foo", "bar", "baz")); 

编程接口,而不是实现

你说你已经在你的代码中声明了ArrayList ,但是你不应该这样做,除非你使用ArrayList中不在List中的一些成员,例如ArrayList.ensureCapacity() 。 这几乎从来没有。

通常你应该只使用最常用的接口来声明variables(例如IterableCollection或者List ),然后用特定的实现(比如ArrayListLinkedList或者Arrays.asList() )对它们进行初始化。

否则,你会限制你的代码到那个特定的types,当你想要更改的时候会很难。

例如:

 // Iterable if you just need iteration, for (String s : strings): Iterable<String> strings = new ArrayList<>(); // Collection if you also need .size() or .stream(): Collection<String> strings = new ArrayList<>(); // List if you also need .get(index): List<String> strings = new ArrayList<>(); // Don't declare a specific list implementation // unless you're sure you need it: ArrayList<String> strings = new ArrayList<>(); // You don't need ArrayList 

另一个例子是总是声明variablesInputStream即使它通常是一个FileInputStream或一个BufferedInputStream ,因为有一天你或别人会想要使用其他types的InputStream

如果你需要一个简单的大小列表1:

 List<String> strings = new ArrayList<String>(Collections.singletonList("A")); 

如果您需要几个对象的列表:

 List<String> strings = new ArrayList<String>(); Collections.addAll(strings,"A","B","C","D"); 

用番石榴你可以写:

 ArrayList<String> places = Lists.newArrayList("Buenos Aires", "Córdoba", "La Plata")); 

在番石榴还有其他有用的静态构造函数。 你可以在这里阅读。

集合文字没有进入Java 8,但是可以使用Stream API来在一个相当长的行中初始化一个列表:

 List<String> places = Stream.of("Buenos Aires", "Córdoba", "La Plata").collect(Collectors.toList()); 

如果你需要确保你的List是一个ArrayList

 ArrayList<String> places = Stream.of("Buenos Aires", "Córdoba", "La Plata").collect(Collectors.toCollection(ArrayList::new)); 
 import com.google.common.collect.ImmutableList; .... List<String> places = ImmutableList.of("Buenos Aires", "Córdoba", "La Plata"); 

你可以创build一个工厂方法:

 public static ArrayList<String> createArrayList(String ... elements) { ArrayList<String> list = new ArrayList<String>(); for (String element : elements) { list.add(element); } return list; } .... ArrayList<String> places = createArrayList( "São Paulo", "Rio de Janeiro", "Brasília"); 

但是这并不比你的第一次重构好得多。

更新:为了更大的灵活性,它可以是通用的:

 public static <T> ArrayList<T> createArrayList(T ... elements) { ArrayList<T> list = new ArrayList<T>(); for (T element : elements) { list.add(element); } return list; } 

使用Java 9 ,正如JDK增强build议-269所build议的那样,现在可以使用集合文字来实现这一点 –

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

另外一个类似的方法也适用于Map

 Map<String, String> map = Map.of("k1", "v1", "k2", "v2", "k3", "v3") 

这与@coobird所述的Collection Literals 提案类似。 在JEP文档中进一步阐明了这一点 –


备择scheme

语言的变化已经被多次考虑,并被拒绝了:

项目硬币提案,2009年3月29日

项目硬币提案,2009年3月30日

JEP 186讨论lambda-dev,2014年1月至3月

语言提议被搁置,而不是本报告中总结的基于图书馆的提案。

链接阅读大约相同〜> 重载便利工厂方法有什么意义

你可以使用下面的语句:

代码片段:

 String [] arr = {"Sharlock", "Homes", "Watson"}; List<String> names = Arrays.asList(arr); 

关于最紧凑的方法是:

 Double array[] = { 1.0, 2.0, 3.0}; List<Double> list = Arrays.asList(array); 

使用Eclipse Collections (以前称为GS Collections ),您可以编写以下内容:

 List<String> list = Lists.mutable.with("Buenos Aires", "Córdoba", "La Plata"); 

你也可以更具体的types,是否可变或不可变。

 MutableList<String> mList = Lists.mutable.with("Buenos Aires", "Córdoba", "La Plata"); ImmutableList<String> iList = Lists.immutable.with("Buenos Aires", "Córdoba", "La Plata"); 

你也可以用套装和手袋来做同样的事情:

 Set<String> set = Sets.mutable.with("Buenos Aires", "Córdoba", "La Plata"); MutableSet<String> mSet = Sets.mutable.with("Buenos Aires", "Córdoba", "La Plata"); ImmutableSet<String> iSet = Sets.immutable.with("Buenos Aires", "Córdoba", "La Plata"); Bag<String> bag = Bags.mutable.with("Buenos Aires", "Córdoba", "La Plata"); MutableBag<String> mBag = Bags.mutable.with("Buenos Aires", "Córdoba", "La Plata"); ImmutableBag<String> iBag = Bags.immutable.with("Buenos Aires", "Córdoba", "La Plata"); 

注意:我是Eclipse集合的提交者。

简单地使用如下。

 List<String> list = new ArrayList<String>() {{ add("A"); add("B"); add("C"); }}; 

(应该是一个评论,但太长,如此新的答复)。 正如其他人所提到的,Arrays.asList方法的大小是固定的,但这不是唯一的问题。 它也不能很好地处理inheritance。 例如,假设你有以下几点:

 class A{} class B extends A{} public List<A> getAList(){ return Arrays.asList(new B()); } 

上面的结果导致编译器错误,因为List<B> (这是Arrays.asList返回的内容)不是List<A>的子类,即使可以将typesB的对象添加到List<A>对象。 为了解决这个问题,你需要做一些事情:

 new ArrayList<A>(Arrays.<A>asList(b1, b2, b3)) 

这可能是这样做的最好方法,尤其是。 如果你需要一个无界列表或需要使用inheritance。

像汤姆说的那样 :

 List<String> places = Arrays.asList("Buenos Aires", "Córdoba", "La Plata"); 

但是既然你抱怨想要一个ArrayList,你应该首先知道ArrayList是List的一个子类,你可以简单的添加下面这行:

 ArrayList<String> myPlaces = new ArrayList(places); 

虽然这可能会让你抱怨“performance”。

在这种情况下,对我来说这是没有意义的,为什么呢,因为你的列表是预定义的,所以它没有被定义为一个数组(因为在初始化的时候已经知道了这个大小)。 如果这是您的select:

 String[] places = {"Buenos Aires", "Córdoba", "La Plata"}; 

如果你不关心性能差异,那么你也可以非常简单地将数组复制到ArrayList:

 ArrayList<String> myPlaces = new ArrayList(Arrays.asList(places)); 

好的,但是将来你需要的不仅仅是地名,还需要一个国家代码。 假设这仍然是一个预定义的列表,在运行时永远不会改变,那么使用enum集是合适的,如果将来需要更改列表,则需要重新编译。

 enum Places {BUENOS_AIRES, CORDOBA, LA_PLATA} 

会成为:

 enum Places { BUENOS_AIRES("Buenos Aires",123), CORDOBA("Córdoba",456), LA_PLATA("La Plata",789); String name; int code; Places(String name, int code) { this.name=name; this.code=code; } } 

枚举有一个静态values方法返回一个数组包含枚举的所有值的声明,例如:

 for (Places p:Places.values()) { System.out.printf("The place %s has code %d%n", p.name, p.code); } 

在这种情况下,我猜你不需要你的ArrayList。

PS Randyaa演示了使用静态工具方法Collections.addAll的另一个好方法。

这是另一种方式:

 List<String> values = Stream.of("One", "Two").collect(Collectors.toList()); 
 List<String> names = Arrays.asList("2","@2234","21","11"); 

试试这个代码行:

 Collections.singletonList(provider) 

Java 9有以下方法来创build一个不可变列表:

 List<String> places = List.of("Buenos Aires", "Córdoba", "La Plata"); 

如果需要的话,它很容易适应创build一个可变列表:

 List<String> places = new ArrayList<>(List.of("Buenos Aires", "Córdoba", "La Plata")); 

类似的方法可用于SetMap

您可以使用StickyList的StickyList :

 List<String> names = new StickyList<>( "Scott Fitzgerald", "Fyodor Dostoyevsky" ); 

在Java中,你不能这样做

 ArrayList<String> places = new ArrayList<String>( Arrays.asList("Buenos Aires", "Córdoba", "La Plata")); 

正如所指出的,你需要做一个双括号初始化:

 List<String> places = new ArrayList<String>() {{ add("x"); add("y"); }}; 

但是这可能会迫使你添加注解@SuppressWarnings("serial")或生成一个烦人的串行UUID。 而且大多数代码格式化器将把它解包成多个语句/行。

或者你可以做

 List<String> places = Arrays.asList(new String[] {"x", "y" }); 

但是你可能想要做一个@SuppressWarnings("unchecked")

另外根据javadoc你应该能够做到这一点:

 List<String> stooges = Arrays.asList("Larry", "Moe", "Curly"); 

但是我不能用JDK 1.6来编译它。

是的,在数组的帮助下,您可以将数组列表初始化为一行,

 List<String> strlist= Arrays.asList("aaa", "bbb", "ccc"); 

这里是AbacusUtil的代码

 // ArrayList List<String> list = N.asList("Buenos Aires", "Córdoba", "La Plata"); // HashSet Set<String> set = N.asSet("Buenos Aires", "Córdoba", "La Plata"); // HashMap Map<String, Integer> map = N.asMap("Buenos Aires", 1, "Córdoba", 2, "La Plata", 3); // Or for Immutable List/Set/Map ImmutableList.of("Buenos Aires", "Córdoba", "La Plata"); ImmutableSet.of("Buenos Aires", "Córdoba", "La Plata"); ImmutableSet.of("Buenos Aires", 1, "Córdoba", 2, "La Plata", 3); // The most efficient way, which is similar with Arrays.asList(...) in JDK. // but returns a flexible-size list backed by the specified array. List<String> set = Array.asList("Buenos Aires", "Córdoba", "La Plata"); 

声明:我是AbacusUtil的开发人员。

 Collections.singletonList(messageBody) 

如果你需要有一个项目的列表!

集合来自java.util包。

最好的方法来做到这一点:

 package main_package; import java.util.ArrayList; public class Stackkkk { public static void main(String[] args) { ArrayList<Object> list = new ArrayList<Object>(); add(list, "1", "2", "3", "4", "5", "6"); System.out.println("I added " + list.size() + " element in one line"); } public static void add(ArrayList<Object> list,Object...objects){ for(Object object:objects) list.add(object); } } 

只需要创build一个可以包含尽可能多的元素的函数,并将其添加到一行中即可。

有时我只是觉得人们应该简单地使用Groovy ,让Java平静下来。 好的是,它运行在JVM上,所以你可以将纯Java代码粘贴到Groovy文件中的任何地方,它就可以工作。

关于在一行中声明列表,这是它在Groovy中的样子:

 def list1 = [1,2,3] 

就这样,马恩!

这里更多的Groovy列表 。

附加function

在Groovy中声明一个地图:

 def map1 = [key1:1,key2:2] 

这里更多的是在Groovy地图上 。

读一个JSON文件,

 { "map1":{"map2":{"key":"value1"}}} 

一行如下:

 String value = new JsonSlurper().parse("path\\to\\file")["map1"]["map2"]["key"] 

要么

 String value = new JsonSlurper().parse("path\\to\\file").map1.map2.key 

两者都将value设置为value1

想象一下,与jacksonAPI一样。 您必须为map1和map2编写相应的POJO 。 然后编译。 每当JSON发生变化时,您都必须在POJO中反映这些变化。 这完全击败了使JSONfunction可configuration的目标。 这是致命的configuration代码重新编译链。 不只是configuration和去。

当我被要求使用Java时,我哭了。 为什么世界为什么 (或者如果我错了,请赐教…在Java世界中会减less我很多的痛苦)

在Java 9中,我们可以轻松地在一行中初始化一个ArrayList

 List<String> places = List.of("Buenos Aires", "Córdoba", "La Plata"); 

要么

 List<String> places = new ArrayList<>(List.of("Buenos Aires", "Córdoba", "La Plata")); 

Java 9的这种新方法比以前的方法有许多优点:

  1. 空间效率
  2. 不变性
  3. 线程安全

看到这个post的更多细节 – > List.of和Arrays.asList有什么区别?

对我来说Arrays.asList()是最好的和方便的。 我总是喜欢这样初始化。 如果你是Java Collections的初学者,那么我希望你引用ArrayList初始化

实际上,可以在一行中完成:

 Arrays.asList(new MyClass[] {new MyClass("arg1"), new MyClass("arg2")}) 
 public static <T> List<T> asList(T... a) { return new ArrayList<T>(a); } 

这是Arrays.asList的实现,所以你可以去

 ArrayList<String> arr = (ArrayList<String>) Arrays.asList("1", "2");