如何将 List转换为Java 中的 int[] ?

发布于 2024-10-17 04:53:39 字数 605 浏览 1 评论 0原文

如何在 Java 中将 List 转换为 int[]

我很困惑,因为 List.toArray() 实际上返回一个 Object[],它既不能转换为 Integer[] 也不能转换为 int[]

现在我正在使用循环来执行此操作:

int[] toIntArray(List<Integer> list) {
  int[] ret = new int[list.size()];
  for(int i = 0; i < ret.length; i++)
    ret[i] = list.get(i);
  return ret;
}

有更好的方法吗?

这与问题类似 如何在 Java 中将 int[] 转换为 Integer[]?< /em>.

How can I convert a List<Integer> to int[] in Java?

I'm confused because List.toArray() actually returns an Object[], which can be cast to neither Integer[] nor int[].

Right now I'm using a loop to do so:

int[] toIntArray(List<Integer> list) {
  int[] ret = new int[list.size()];
  for(int i = 0; i < ret.length; i++)
    ret[i] = list.get(i);
  return ret;
}

Is there's a better way to do this?

This is similar to the question
How can I convert int[] to Integer[] in Java?.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

时光礼记 2024-10-24 04:53:39

通过 Java 8 中添加的流,我们可以编写如下代码:

int[] example1 = list.stream().mapToInt(i->i).toArray();
// OR
int[] example2 = list.stream().mapToInt(Integer::intValue).toArray();

思考过程:

  • 简单的 Stream#toArray 返回一个 Object[] 数组,因此它不是我们想要的想。另外,返回 A[] 的 Stream#toArray(IntFunction Generator) 并不能满足我们的要求,因为泛型类型 A 无法表示原始类型 int

  • 因此,最好有某种设计为处理原始类型 int 的流像 Integer 这样的引用类型,因为它的 toArray 方法很可能也会返回一个 int[] 数组(返回像 Object[] 甚至装箱的 Integer[] 对于 int 来说都是不自然的)。幸运的是,Java 8 有这样一个流,它是 <代码>IntStream

  • 所以现在我们唯一需要弄清楚的是如何转换我们的 Stream (它将从 list 返回.stream()) 到闪亮的 IntStream

    Stream 文档中快速搜索,同时寻找返回 IntStream 的方法,这为我们指明了我们的解决方案,即 mapToInt(ToIntFunction 映射器) 方法。我们需要做的就是提供从 Integerint 的映射。

    ToIntFunction函数接口,我们还可以通过lambda方法引用提供它的实例。

    无论如何,要将 Integer 转换为 int,我们可以使用 Integer#intValue 所以在 mapToInt 中我们可以这样写:

    mapToInt( (整数 i) -> i.intValue() )
    

    (或者有些人可能更喜欢:mapToInt(Integer::intValue)。)

    但是可以使用拆箱生成类似的代码,因为编译器知道此 lambda 的结果必须是 int 类型(mapToInt 中使用的 lambda 是一个实现ToIntFunction 接口的主体,该接口期望类型为 int applyAsInt(T value) 的方法作为主体,该方法预计返回一个 int)。< /p>

    所以我们可以简单地写:

    mapToInt((整数 i)->i)
    

    此外,由于 (Integer i) 中的 Integer 类型可以由编译器推断出来,因为 List#stream()返回一个 Stream,我们也可以跳过它,留下

    mapToInt(i -> i)
    

With streams added in Java 8 we can write code like:

int[] example1 = list.stream().mapToInt(i->i).toArray();
// OR
int[] example2 = list.stream().mapToInt(Integer::intValue).toArray();

Thought process:

  • The simple Stream#toArray returns an Object[] array, so it is not what we want. Also, Stream#toArray(IntFunction<A[]> generator) which returns A[] doesn't do what we want, because the generic type A can't represent the primitive type int

  • So it would be nice to have some kind of stream which would be designed to handle primitive type int instead of the reference type like Integer, because its toArray method will most likely also return an int[] array (returning something else like Object[] or even boxed Integer[] would be unnatural for int). And fortunately Java 8 has such a stream which is IntStream

  • So now the only thing we need to figure out is how to convert our Stream<Integer> (which will be returned from list.stream()) to that shiny IntStream.

    Quick searching in documentation of Stream while looking for methods which return IntStream points us to our solution which is mapToInt(ToIntFunction<? super T> mapper) method. All we need to do is provide a mapping from Integer to int.

    Since ToIntFunction is functional interface we can also provide its instance via lambda or method reference.

    Anyway to convert Integer to int we can use Integer#intValue so inside mapToInt we can write:

    mapToInt( (Integer i) -> i.intValue() )
    

    (or some may prefer: mapToInt(Integer::intValue).)

    But similar code can be generated using unboxing, since the compiler knows that the result of this lambda must be of type int (the lambda used in mapToInt is an implementation of the ToIntFunction interface which expects as body a method of type: int applyAsInt(T value) which is expected to return an int).

    So we can simply write:

    mapToInt((Integer i)->i)
    

    Also, since the Integer type in (Integer i) can be inferred by the compiler because List<Integer>#stream() returns a Stream<Integer>, we can also skip it which leaves us with

    mapToInt(i -> i)
    
分分钟 2024-10-24 04:53:39

不幸的是,由于 Java 处理原始类型、装箱、数组和泛型的性质,我不认为真的有更好的方法来做到这一点。特别是:

  • List.toArray 不起作用,因为没有从 Integerint 的转换
  • 您不能使用 int 作为泛型的类型参数,因此它必须是一种 int 特定的方法(或者使用反射来进行令人讨厌的欺骗的方法)。

我相信有些库为所有原始类型提供了这种方法的自动生成版本(即有一个为每种类型复制的模板)。它很丑陋,但恐怕就是这样:(

尽管 Arrays 类在泛型到达 Java 之前就出现了,如果今天引入它,它仍然必须包含所有可怕的重载(假设您想使用原始数组) 。

Unfortunately, I don't believe there really is a better way of doing this due to the nature of Java's handling of primitive types, boxing, arrays and generics. In particular:

  • List<T>.toArray won't work because there's no conversion from Integer to int
  • You can't use int as a type argument for generics, so it would have to be an int-specific method (or one which used reflection to do nasty trickery).

I believe there are libraries which have autogenerated versions of this kind of method for all the primitive types (i.e. there's a template which is copied for each type). It's ugly, but that's the way it is I'm afraid :(

Even though the Arrays class came out before generics arrived in Java, it would still have to include all the horrible overloads if it were introduced today (assuming you want to use primitive arrays).

晨敛清荷 2024-10-24 04:53:39

除了 Commons Lang 之外,您还可以使用 Guava 的方法 Ints.toArray (Collection集合)

List<Integer> list = ...
int[] ints = Ints.toArray(list);

这样您就不必自己进行 Commons Lang 等效项所需的中间数组转换。

In addition to Commons Lang, you can do this with Guava's method Ints.toArray(Collection<Integer> collection):

List<Integer> list = ...
int[] ints = Ints.toArray(list);

This saves you having to do the intermediate array conversion that the Commons Lang equivalent requires yourself.

雪落纷纷 2024-10-24 04:53:39

最简单的方法是使用 Apache Commons Lang。它有一个方便的 ArrayUtils 类,可以做你想做的事情。使用 toPrimitive 方法,具有 Integer 数组的重载。

List<Integer> myList;
 ... assign and fill the list
int[] intArray = ArrayUtils.toPrimitive(myList.toArray(new Integer[myList.size()]));

这样你就不会重新发明轮子。 Commons Lang 有很多 Java 所遗漏的有用的东西。在上面,我选择创建一个适当大小的整数列表。您还可以使用 0 长度的静态整数数组,并让 Java 分配正确大小的数组:

static final Integer[] NO_INTS = new Integer[0];
   ....
int[] intArray2 = ArrayUtils.toPrimitive(myList.toArray(NO_INTS));

The easiest way to do this is to make use of Apache Commons Lang. It has a handy ArrayUtils class that can do what you want. Use the toPrimitive method with the overload for an array of Integers.

List<Integer> myList;
 ... assign and fill the list
int[] intArray = ArrayUtils.toPrimitive(myList.toArray(new Integer[myList.size()]));

This way you don't reinvent the wheel. Commons Lang has a great many useful things that Java left out. Above, I chose to create an Integer list of the right size. You can also use a 0-length static Integer array and let Java allocate an array of the right size:

static final Integer[] NO_INTS = new Integer[0];
   ....
int[] intArray2 = ArrayUtils.toPrimitive(myList.toArray(NO_INTS));
瘫痪情歌 2024-10-24 04:53:39

Java 8 为我们提供了一种通过流来完成此操作的简单方法...

使用集合 stream() 函数,然后映射到整数,您将获得一个 IntStream。使用 IntStream 我们可以调用 toArray() ,它给我们 int []

int [] ints = list.stream().mapToInt(Integer::intValue).toArray();

到 int []

到 IntStream

Java 8 has given us an easy way to do this via streams...

Using the collections stream() function and then mapping to ints, you'll get an IntStream. With the IntStream we can call toArray() which gives us int []

int [] ints = list.stream().mapToInt(Integer::intValue).toArray();

to int []

to IntStream

感性不性感 2024-10-24 04:53:39

用途:

int[] toIntArray(List<Integer> list)  {
    int[] ret = new int[list.size()];
    int i = 0;
    for (Integer e : list)
        ret[i++] = e;
    return ret;
}

对代码的这一微小更改是为了避免昂贵的列表索引(因为列表不一定是 ArrayList,但它可能是链表,对于其随机访问来说成本很高)。

Use:

int[] toIntArray(List<Integer> list)  {
    int[] ret = new int[list.size()];
    int i = 0;
    for (Integer e : list)
        ret[i++] = e;
    return ret;
}

This slight change to your code is to avoid expensive list indexing (since a List is not necessarily an ArrayList, but it could be a linked list, for which random access is expensive).

顾忌 2024-10-24 04:53:39

下面是一个 Java 8 单行代码:

public int[] toIntArray(List<Integer> intList){
    return intList.stream().mapToInt(Integer::intValue).toArray();
}

Here is a Java 8 single line code for this:

public int[] toIntArray(List<Integer> intList){
    return intList.stream().mapToInt(Integer::intValue).toArray();
}
書生途 2024-10-24 04:53:39

如果您只是将 Integer 映射到 int 那么您应该考虑 使用并行性,因为您的映射逻辑不依赖于其范围之外的任何变量。

int[] arr = list.parallelStream().mapToInt(Integer::intValue).toArray();

请注意这一点

请注意,并行性并不自动比串行执行操作更快,尽管如果您有足够的数据和处理器内核,则可能会更快。虽然聚合操作使您能够更轻松地实现并行性,但您仍然有责任确定您的应用程序是否适合并行性。


有两种方法可以将整数映射到其原始形式:

  1. 通过 ToIntFunction

    mapToInt(Integer::intValue)
    
  2. 通过使用 lambda 表达式显式拆箱

    mapToInt(i -> i.intValue())
    
  3. 通过使用 lambda 表达式隐式(自动)拆箱。

    mapToInt(i -> i)
    

给定一个带有 null 值的列表

List<Integer> list = Arrays.asList(1, 2, null, 4, 5);

以下是处理 null 的三个选项:

  1. 在映射之前过滤掉 null 值。

    int[] arr = list.parallelStream().filter(Objects::nonNull).mapToInt(Integer::intValue).toArray();
    
  2. null 值映射到默认值。

    int[] arr = list.parallelStream().map(i -> i == null ? -1 : i).mapToInt(Integer::intValue).toArray();
    
  3. 在 lambda 表达式中处理 null

    int[] arr = list.parallelStream().mapToInt(i -> i == null ? -1 : i.intValue()).toArray();
    

If you are simply mapping an Integer to an int then you should consider using parallelism, since your mapping logic does not rely on any variables outside its scope.

int[] arr = list.parallelStream().mapToInt(Integer::intValue).toArray();

Just be aware of this

Note that parallelism is not automatically faster than performing operations serially, although it can be if you have enough data and processor cores. While aggregate operations enable you to more easily implement parallelism, it is still your responsibility to determine if your application is suitable for parallelism.


There are two ways to map Integers to their primitive form:

  1. Via a ToIntFunction.

    mapToInt(Integer::intValue)
    
  2. Via explicit unboxing with lambda expression.

    mapToInt(i -> i.intValue())
    
  3. Via implicit (auto-) unboxing with lambda expression.

    mapToInt(i -> i)
    

Given a list with a null value

List<Integer> list = Arrays.asList(1, 2, null, 4, 5);

Here are three options to handle null:

  1. Filter out the null values before mapping.

    int[] arr = list.parallelStream().filter(Objects::nonNull).mapToInt(Integer::intValue).toArray();
    
  2. Map the null values to a default value.

    int[] arr = list.parallelStream().map(i -> i == null ? -1 : i).mapToInt(Integer::intValue).toArray();
    
  3. Handle null inside the lambda expression.

    int[] arr = list.parallelStream().mapToInt(i -> i == null ? -1 : i.intValue()).toArray();
    
梦里寻她 2024-10-24 04:53:39

这个简单的循环总是正确的!没有错误

  int[] integers = new int[myList.size()];
  for (int i = 0; i < integers.length; i++) {
      integers[i] = myList.get(i);
  }

This simple loop is always correct! no bugs

  int[] integers = new int[myList.size()];
  for (int i = 0; i < integers.length; i++) {
      integers[i] = myList.get(i);
  }
晨曦慕雪 2024-10-24 04:53:39

我注意到 for 循环的多种用途,但您甚至不需要循环内的任何内容。我提到这一点只是因为最初的问题是试图找到不太冗长的代码。

int[] toArray(List<Integer> list) {
    int[] ret = new int[ list.size() ];
    int i = 0;
    for( Iterator<Integer> it = list.iterator();
         it.hasNext();
         ret[i++] = it.next() );
    return ret;
}

如果 Java 允许像 C++ 那样在 for 循环中进行多个声明,我们可以更进一步,执行 for(int i = 0, Iterator it...

但最后(这部分只是我的观点),如果你想要一个帮助你做某事的功能或方法,只需设置它并忘记它,如果你再也不会看它,它可以是一行或十行;不会知道其中的区别。

I've noticed several uses of for loops, but you don't even need anything inside the loop. I mention this only because the original question was trying to find less verbose code.

int[] toArray(List<Integer> list) {
    int[] ret = new int[ list.size() ];
    int i = 0;
    for( Iterator<Integer> it = list.iterator();
         it.hasNext();
         ret[i++] = it.next() );
    return ret;
}

If Java allowed multiple declarations in a for loop the way C++ does, we could go a step further and do for(int i = 0, Iterator it...

In the end though (this part is just my opinion), if you are going to have a helping function or method to do something for you, just set it up and forget about it. It can be a one-liner or ten; if you'll never look at it again you won't know the difference.

只为守护你 2024-10-24 04:53:39

实际上没有办法“单行”你想要做的事情,因为 toArray 返回一个 Object[] 并且你不能从 Object[] 转换为 int[] 或 Integer[] 转换为 int[] 。

There is really no way of "one-lining" what you are trying to do, because toArray returns an Object[] and you cannot cast from Object[] to int[] or Integer[] to int[].

各自安好 2024-10-24 04:53:39
int[] ret = new int[list.size()];       
Iterator<Integer> iter = list.iterator();
for (int i=0; iter.hasNext(); i++) {       
    ret[i] = iter.next();                
}                                        
return ret;                              
int[] ret = new int[list.size()];       
Iterator<Integer> iter = list.iterator();
for (int i=0; iter.hasNext(); i++) {       
    ret[i] = iter.next();                
}                                        
return ret;                              
┼── 2024-10-24 04:53:39

另请尝试美元 (检查此修订版):

import static com.humaorie.dollar.Dollar.*
...

List<Integer> source = ...;
int[] ints = $(source).convert().toIntArray();

Also try Dollar (check this revision):

import static com.humaorie.dollar.Dollar.*
...

List<Integer> source = ...;
int[] ints = $(source).convert().toIntArray();
笨笨の傻瓜 2024-10-24 04:53:39

使用 Eclipse Collections,如果您有 java.util 类型的列表,则可以执行以下操作.List

List<Integer> integers = Lists.mutable.with(1, 2, 3, 4, 5);
int[] ints = LazyIterate.adapt(integers).collectInt(i -> i).toArray();

Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, ints);

如果您已经有一个 Eclipse Collections 类型,例如 MutableList,您可以执行以下操作:

MutableList<Integer> integers = Lists.mutable.with(1, 2, 3, 4, 5);
int[] ints = integers.asLazy().collectInt(i -> i).toArray();

Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, ints);

注意:我是 Eclipse Collections 的提交者

With Eclipse Collections, you can do the following if you have a list of type java.util.List<Integer>:

List<Integer> integers = Lists.mutable.with(1, 2, 3, 4, 5);
int[] ints = LazyIterate.adapt(integers).collectInt(i -> i).toArray();

Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, ints);

If you already have an Eclipse Collections type like MutableList, you can do the following:

MutableList<Integer> integers = Lists.mutable.with(1, 2, 3, 4, 5);
int[] ints = integers.asLazy().collectInt(i -> i).toArray();

Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, ints);

Note: I am a committer for Eclipse Collections

一直在等你来 2024-10-24 04:53:39

我建议您使用 Java 集合 API 中的 List 骨架实现。在这种特殊情况下,它似乎非常有帮助:

package mypackage;

import java.util.AbstractList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class Test {

    // Helper method to convert int arrays into Lists
    static List<Integer> intArrayAsList(final int[] a) {
        if(a == null)
            throw new NullPointerException();
        return new AbstractList<Integer>() {

            @Override
            public Integer get(int i) {
                return a[i]; // Autoboxing
            }
            @Override
            public Integer set(int i, Integer val) {
                final int old = a[i];
                a[i] = val; // Auto-unboxing
                return old; // Autoboxing
            }
            @Override
            public int size() {
                return a.length;
            }
        };
    }

    public static void main(final String[] args) {
        int[] a = {1, 2, 3, 4, 5};
        Collections.reverse(intArrayAsList(a));
        System.out.println(Arrays.toString(a));
    }
}

谨防装箱/拆箱缺点。

I would recommend you to use the List<?> skeletal implementation from the Java collections API. It appears to be quite helpful in this particular case:

package mypackage;

import java.util.AbstractList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class Test {

    // Helper method to convert int arrays into Lists
    static List<Integer> intArrayAsList(final int[] a) {
        if(a == null)
            throw new NullPointerException();
        return new AbstractList<Integer>() {

            @Override
            public Integer get(int i) {
                return a[i]; // Autoboxing
            }
            @Override
            public Integer set(int i, Integer val) {
                final int old = a[i];
                a[i] = val; // Auto-unboxing
                return old; // Autoboxing
            }
            @Override
            public int size() {
                return a.length;
            }
        };
    }

    public static void main(final String[] args) {
        int[] a = {1, 2, 3, 4, 5};
        Collections.reverse(intArrayAsList(a));
        System.out.println(Arrays.toString(a));
    }
}

Beware of boxing/unboxing drawbacks.

懒猫 2024-10-24 04:53:39

使用 lambda 你可以这样做(在 JDK lambda 中编译):

public static void main(String ars[]) {
    TransformService transformService = (inputs) -> {
        int[] ints = new int[inputs.size()];
        int i = 0;
        for (Integer element : inputs) {
            ints[ i++ ] = element;
        }
        return ints;
    };

    List<Integer> inputs = new ArrayList<Integer>(5) { {add(10); add(10);} };

    int[] results = transformService.transform(inputs);
}

public interface TransformService {
    int[] transform(List<Integer> inputs);
}

Using a lambda you could do this (compiles in JDK lambda):

public static void main(String ars[]) {
    TransformService transformService = (inputs) -> {
        int[] ints = new int[inputs.size()];
        int i = 0;
        for (Integer element : inputs) {
            ints[ i++ ] = element;
        }
        return ints;
    };

    List<Integer> inputs = new ArrayList<Integer>(5) { {add(10); add(10);} };

    int[] results = transformService.transform(inputs);
}

public interface TransformService {
    int[] transform(List<Integer> inputs);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文