[英]How to create ArrayList (ArrayList<T>) from array of primitive type elements
public class Main {
public static void main(String[] args) {
byte[] a=new byte[3];
List<Byte> c=new ArrayList<Byte>();
c.addAll(Arrays.asList(a));
//The method addAll(Collection<? extends Byte>) in the type List<Byte>
//is not applicable for the arguments (List<byte[]>)
Collections.addAll(c, a);
//The method addAll(Collection<? super T>, T...) in the type Collections
//is not applicable for the arguments (List<Byte>, byte[])
}
}
Last two lines give compile error. 最后两行给出编译错误。
To fix it, firstly I read this Create ArrayList from array discussing. 为了解决这个问题,首先我从数组讨论中读取了此Create ArrayList 。 I try this solution, but it don't work.
我尝试了这种解决方案,但是它不起作用。 Here Converting array to list in Java is explain, why it don't work, but isn't solution.
这里解释了如何在Java中将数组转换为列表 ,为什么它不起作用,但不是解决方案。
"source array is a primitive array of bytes, instead of Byte objects" is true, and I hope, that exists more beautibul solution, then iterate and cast each element. “源数组是字节的原始数组,而不是字节对象”是正确的,我希望存在更多的美丽解决方案,然后迭代并转换每个元素。
Your array must be an array of Byte, not byte. 您的数组必须是字节数组,而不是字节数组。 addAll requires a collection of objects that match.
addAll需要匹配的对象的集合。
In other words: Byte[] a=new Byte[3]; 换句话说:Byte [] a = new Byte [3];
Alternatively, if your source array is a primitive array of bytes, instead of Byte objects, then you have to loop through them and add one at a time: 另外,如果您的源数组是原始的字节数组,而不是Byte对象,则必须遍历它们并一次添加一个:
for( byte toInsert: a ){
c.add((Byte)a);// Probably don't need the cast, but included for clarity
}
It is not possible with standard Java to have Collections on primitive types. 标准Java不可能在基本类型上具有Collections。 However there are some libraries available (like trove or apache commons primitives ) to achieve this.
但是,有一些可用的库(例如trove或apache commons原语 )可以实现此目的。
This has great performance implications. 这具有很大的性能影响。 The Boxed Types of the primitives have a massive amount of (mostly unneeded) overhead, because every boxed object extends the java basic
Object
(i think the overhead is somewhere at 8 bytes per object). 原语的Boxed Types具有大量(几乎不需要)开销,因为每个Boxed对象都扩展了Java Basic
Object
(我认为每个对象的开销约为8个字节)。 I a List with for instance 1000 Integers you have 1000 times the overhead, which can be bad for your memory. 我有一个列表,例如1000个Integer,那么您的开销是1000倍,这可能对您的内存不利。 So if memory consumption is an issue, primitive collections are a great way to deal with it.
因此,如果内存消耗是一个问题,则原始集合是解决此问题的好方法。
If Memory conspumtion is not a problem, you can use the boxed types and jazees answer 如果内存消耗不成问题,则可以使用带框的类型和jazees答案
With Java 8 you can use streams do it in a single statement, without the casting and iteration you want to avoid: 使用Java 8,您可以使用流在单个语句中完成操作,而无需进行强制转换和迭代:
byte[] byteArray = {-128, 89, 103, 92, 0, 127};
List<Byte> byteList = IntStream.range(0, byteArray.length)
.mapToObj((int i) -> byteArray[i])
.collect(Collectors.toList());
System.out.println("byteList = " + byteList);
The basic idea is to get the array values into a Stream, then load those stream values into a List: 基本思想是将数组值放入Stream中,然后将这些流值加载到List中:
You can use the same approach for char[] and short[] transformations. 您可以对char []和short []转换使用相同的方法。
In Java, there are classes that "wrap" around primitive types, so to speak. 可以这么说,在Java中,有些类可以“包装”原始类型。 These classes are: Integer, Byte, Long, Double, Float, Character, etc.
这些类是:整数,字节,长整数,双精度,浮点数,字符等。
Now here are the primitive types: int, byte, long, double, float, char, etc. 现在这里是原始类型:int,byte,long,double,float,char等。
You see the similarity? 您看到相似之处了吗? So when you are using type parameters (notated like this: ), you have to use these wrapper classes instead of the primitive types because primitives aren't classes (that's why String isn't a primitive but it is a class.) You can add primitive types like "byte b = 1" to the list you have up there, but because the array you have doesn't match the class of your list, it doesn't work.
因此,当您使用类型参数(用这样的符号表示:)时,您必须使用这些包装类而不是原始类型,因为原始不是类(这就是为什么String不是原始但它是一个类的原因。)将原始类型(例如“ byte b = 1”)添加到您所在的列表中,但是由于您拥有的数组与列表的类不匹配,因此无法使用。
It's an easy fix, just changed the type of your array from "byte" to "Byte." 这很容易解决,只需将数组的类型从“字节”更改为“字节”即可。
The simple way I would recommend to new programmers: 我向新程序员推荐的简单方法是:
static ArrayList<Integer> primitiveArrayToArrayList(int[] input)
{
ArrayList<Integer> result = new ArrayList<>();
for (int i : input)
result.add(i);
return result;
}
The modern way I would recommend to advanced programmers: 我向高级程序员推荐的现代方式:
static ArrayList<Integer> primitiveArrayToArrayList(int[] input)
{
return Arrays.stream(input).boxed().collect(Collectors.toCollection(ArrayList::new));
}
note: Arrays.stream() is only available for int, long, double and reference types 注意:Arrays.stream()仅适用于int,long,double和reference类型
This way allows simple modifications in a more complex use case, like here: 这种方式允许在更复杂的用例中进行简单的修改,例如:
static ArrayList<Integer> findValues(int[] input, Predicate<Integer> filter, int limit)
{
return Arrays.stream(input).boxed().filter(filter).limit(limit).collect(Collectors.toCollection(ArrayList::new));
}
public static void main(String[] args)
{
int[] values = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
Predicate<Integer> filter = i -> i % 2 == 0;
int limit = 3;
System.out.println(findValues(values, filter, limit));
}
converting the Array to an ArrayList, while filtering for even numbers and limit the result size to 3 results in: 将Array转换为ArrayList,同时过滤偶数并将结果大小限制为3,结果是:
out: [0, 2, 4]
Stream API chain vs. loop 流API链与循环
static ArrayList<Integer> findValues(int[] input, Predicate<Integer> filter, int limit)
{
return Arrays.stream(input).boxed().filter(filter).limit(limit).collect(Collectors.toCollection(ArrayList::new));
}
static ArrayList<Integer> findValues(int[] input, Predicate<Integer> filter, int limit)
{
ArrayList<Integer> integers = new ArrayList<>();
for (int i : input)
{
if (filter.test(i))
{
if (limit-- == 0) break;
integers.add(i);
}
}
return integers;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.