在一行中初始化一个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
是不可变的 (试图改变它将导致UnsupportedOperationException
exception被抛出)。
要创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(例如Iterable
, Collection
或者List
),然后用特定的实现(比如ArrayList
, LinkedList
或者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"));
类似的方法可用于Set
和Map
。
您可以使用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的这种新方法比以前的方法有许多优点:
- 空间效率
- 不变性
- 线程安全
看到这个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");