在Java中,将整数列表快速转换为整数数组的方法

20 浏览
0 Comments

在Java中,将整数列表快速转换为整数数组的方法

在Java中,我如何将List转换为int[]?\n我感到困惑的原因是List.toArray()实际上返回一个Object[],无法将其转换为Integer[]int[]。\n目前,我正在使用循环来实现:\n

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

\n有没有更好的方法来完成这个任务?\n这与问题如何将int[]转换为Integer[]在Java中类似。

0
0 Comments

在Java中,将List of Integers转换为int数组的方法有很多。除了使用Commons Lang库之外,还可以使用Guava库中的Ints.toArray方法来实现这个功能。这个方法的用法如下:

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

这样就可以将List中的整数元素转换为int数组了,而无需像使用Commons Lang库一样手动进行中间数组的转换。

然而,使用Guava库的Ints.toArray方法时,中间数组是被隐藏在库内部的:

Object[] boxedArray = collection.toArray();

所以,虽然省去了手动转换中间数组的步骤,但我们无法直接访问中间数组。

幸运的是,Guava库已经为我们解决了这个问题。

以上就是使用Guava库中的Ints.toArray方法将List of Integers转换为int数组的快速方法。通过使用这个方法,我们可以简单地将List中的整数元素转换为int数组,而无需手动进行中间数组的转换。这在处理大量数据时尤为重要,可以提高代码的效率。希望以上内容对你有所帮助!

0
0 Comments

在Java中,将整数列表转换为整数数组的快速方法

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

- List<T>.toArray不起作用,因为没有从Integer到int的转换

- 你不能将int用作泛型的类型参数,所以它必须是一个特定于int的方法(或者使用反射来进行恶心的技巧)。

我相信有一些库已经为所有原始类型自动生成了这种类型的方法(即有一个模板,为每种类型复制一次)。这很丑陋,但这就是现实。

即使在泛型出现之前,Arrays类也已经出现了,如果它是在今天引入的,它仍然必须包含所有可怕的重载(假设你想使用原始数组)。

此外,请参阅ColinD关于guava的Ints.toArray(Collection<Integer>)的答案。

我的意思是,像Arrays类中已经存在的可怕重载,如binarySearch,copyOf,copyOfRange...?我想知道为什么他们不能添加另一组可怕的重载。

ColinD的答案除了OP已经有的(用循环将非原始数组填充到原始数组中)之外,没有提供任何东西。

与此同时,在Oracle的Java工程师们的头脑中,他们一直在用模块过于复杂化语言...

我是说,除非有其他库(基本上仍然在他们的代码中使用循环,而不是你的代码),否则我不认为有更好的方法。这是一个比我不知道是否有更好的方法更有力的断言。

...并且在Java语言设计师改进它之前,你无法避免原始类型-为什么Java中存在原始数据类型的原因。

0
0 Comments

快速将整数列表转换为整数数组的方法

在Java 8中添加了流(stream)之后,我们可以编写如下代码:

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

思路:

- 简单的Stream#toArray方法返回一个Object[]数组,不是我们想要的结果。另外,返回A[]Stream#toArray(IntFunction<A[]> generator)方法也不符合我们的要求,因为泛型类型A无法表示原始类型int

- 所以,我们希望有一种流(stream)可以处理原始类型int,而不是像Integer这样的引用类型,因为它的toArray方法很可能也会返回一个int[]数组(返回其他类型如Object[]或甚至装箱的Integer[]对于int来说是不自然的)。幸运的是,Java 8中有这样的流,它就是IntStream

- 现在我们需要解决的唯一问题是如何将返回的Stream<Integer>(从list.stream()返回)转换为那个闪亮的IntStream

- 在查找返回IntStream的方法时,我们可以快速搜索Stream的文档,找到我们的解决方案,即mapToInt(ToIntFunction<? super T> mapper)方法。我们需要做的就是提供一个从Integerint的映射。

- 由于ToIntFunction是一个函数式接口,我们可以通过lambda方法引用提供它的实例。

- 将Integer转换为int的方法是使用Integer#intValue,所以我们可以在mapToInt中写:

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

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

- 但是,由于编译器知道此lambda的结果必须是int类型(mapToInt中使用的lambda是ToIntFunction接口的实现,它的方法体应该是一个返回int的方法),因此我们可以简单地写成:

mapToInt((Integer i)->i)

- 另外,由于(Integer i)中的Integer类型可以由编译器推断出来,因为List<Integer>#stream()返回一个Stream<Integer>,所以我们也可以省略它,得到:

mapToInt(i -> i)

这显然是最好的解决方案。可惜没有解释。

这个答案更新了一下。希望现在更清楚了。

- 谢谢!我个人不需要解释。但是我不喜欢看到完美的答案没有解释!无论如何,你的解释让我受益匪浅,非常有帮助。我想知道为什么mapTo...函数不允许null lambda,就像sort一样,这样它就可以默认使用默认行为了,例如i -> i将是一个完美的默认行为。

- 我猜这个答案比使用Guava的ColinD的答案更快,对吗?

- 我没有测试过,但我认为这两个解决方案的原理是相同的,所以我希望速度是相似的(但是请随时进行基准测试)。这个答案的一个优点是它不需要额外的库,只要我们有Java 8就可以了。

- 多亏了这个,我了解了原始类型的流。很棒的解决方案和解释,谢谢。

- 毫无疑问,这是最好的解决方案!

- 不幸的是,这似乎不适用于byteshortcharfloat数组...

- 是的,没有与这些原始类型对应的Stream,因此在Stream类中也没有像mapToByte(...)这样的方法。

- 我认为这应该是被接受的答案。另外,如果你愿意,你能否更新答案以使用方法引用?

- 这是等效于字节数组的方法,借鉴了这个答案(以及它的评论):byte[] array = list.stream().filter(Objects::nonNull).mapToInt(i -> i).collect(ByteArrayOutputStream::new, (b, i) -> b.write((byte) i), (b1, b2) -> { try { b2.writeTo(b1); } catch(IOException e) { } }).toByteArray();

- 这正是为什么人们更喜欢Python而不是Java的原因。

0