如何从基本类型元素数组</t>创建ArrayList(ArrayList <t>)

时间:2014-07-06 20:37:02

标签: java arrays arraylist

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[])

}

}

最后两行给出了编译错误。

为了解决这个问题,我首先阅读了这篇文章 Create ArrayList from array 讨论。我尝试这个解决方案,但它不起作用。 这里 Converting array to list in Java 解释,为什么它不起作用,但不是解决方案。

&#34;源数组是一个原始的字节数组,而不是字节对象&#34;是的,我希望,存在更多的美化解决方案,然后迭代并投射每个元素。

5 个答案:

答案 0 :(得分:1)

您的数组必须是Byte数组,而不是byte。 addAll需要一组匹配的对象。

换句话说:     字节[] a =新字节[3];

或者,如果你的源数组是一个原始的字节数组,而不是Byte对象,那么你必须循环遍历它们并一次添加一个:

for( byte toInsert: a ){
   c.add((Byte)a);// Probably don't need the cast, but included for clarity
}

答案 1 :(得分:0)

标准Java无法在基元类型上使用集合。但是,有一些库可用(例如troveapache commons primitives)来实现此目的。

这具有很好的性能影响。 Boxed类型的原语有大量(通常是不需要的)开销,因为每个盒装对象都扩展了java basic Object(我认为开销是每个对象8字节的开销)。我是一个列表,例如1000个整数,你有1000倍的开销,这可能对你的记忆有害。因此,如果内存消耗是一个问题,原始集合是处理它的好方法。

如果Memory conspumtion不是问题,你可以使用盒装类型和jazees回答

答案 2 :(得分:0)

使用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);

基本思想是将数组值放入Stream中,然后将这些流值加载到List中:

  • range()产生对应于索引
    的IntStream 0,1,2,3,4,5 字节数组中的值。
  • mapToObj()产生一个Stream -128,89,103,92,0,127对应 字节数组的值。
  • collect()将这些流值放入List。

您可以对char []和short []转换使用相同的方法。

答案 3 :(得分:0)

在Java中,有一些类可以“包裹”原始类型,可以这么说。这些类是:整数,字节,长整数,双精度,浮点数,字符等

现在这里是原始类型:int,byte,long,double,float,char等。

你看到相似之处吗?因此,当您使用类型参数(如下所示:)时,您必须使用这些包装类而不是基元类型,因为基元不是类(这就是为什么String不是基元而是类的原因。)您可以将“byte b = 1”等基本类型添加到您所在的列表中,但由于您拥有的数组与列表的类不匹配,因此无效。

这是一个简单的修复,只是将数组的类型从“byte”更改为“Byte”。

答案 4 :(得分:0)

我向新程序员推荐的简单方法:

static ArrayList<Integer> primitiveArrayToArrayList(int[] input)
{
    ArrayList<Integer> result = new ArrayList<>();
    for (int i : input)
        result.add(i);
    return result;
}

我向高级程序员推荐的现代方式:

static ArrayList<Integer> primitiveArrayToArrayList(int[] input)
{
    return Arrays.stream(input).boxed().collect(Collectors.toCollection(ArrayList::new));
}

注意:Arrays.stream()仅适用于int,long,double和引用类型

这种方式允许在更复杂的用例中进行简单的修改,例如:

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

将数组转换为ArrayList,同时过滤偶数并将结果大小限制为3,结果为:

out: [0, 2, 4]

Stream 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;
}