Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Guava高效地转换通用数组_Java_Arrays_Function_Transform_Guava - Fatal编程技术网

Java 使用Guava高效地转换通用数组

Java 使用Guava高效地转换通用数组,java,arrays,function,transform,guava,Java,Arrays,Function,Transform,Guava,我正在使用Java7,我正在GuavaAPI中搜索一种方法,将函数应用于数组,而不必首先将其转换为集合。我愿意为此创建自己的类,但我不想重新发明轮子,呵呵 作为一个总结(如果你不知道我在说什么的话),这就是我发现到目前为止你可以用番石榴做的事情,以便将函数应用到数组中,正如我所说的: Integer[] someNumbers = new Integer[]{1, 2, 3}; Integer[] returnedNumbers = Collections2.transform(Arrays.a

我正在使用Java7,我正在GuavaAPI中搜索一种方法,将函数应用于数组,而不必首先将其转换为集合。我愿意为此创建自己的类,但我不想重新发明轮子,呵呵

作为一个总结(如果你不知道我在说什么的话),这就是我发现到目前为止你可以用番石榴做的事情,以便将函数应用到数组中,正如我所说的:

Integer[] someNumbers = new Integer[]{1, 2, 3};
Integer[] returnedNumbers = Collections2.transform(Arrays.asList(someNumbers), squareNumberFunction).toArray(new Integer[0]);

assertThat(returnedNumbers).isEqualTo(new Integer[]{1, 4, 9});//Using AssertJ here
但我希望能够做这样的事情:

Integer[] someNumbers = new Integer[]{1, 2, 3};
Integer[] returnedNumbers = Arrays.transform(someNumbers, squareNumberFunction);

assertThat(returnedNumbers).isEqualTo(new Integer[]{1, 4, 9});
理想情况下,我所说的功能应该是类型安全的


编辑

为了进一步澄清这个问题:

  • 我所说的数组不是基本数组,它们引用的是复杂的对象(我只使用整数来简单地举例说明我所说的)
  • 我无法控制接收的发送的结构,它们数组(如果您认为这有助于更好地理解问题,可以想象一个遗留代码的情况)
  • 转换阵列和访问阵列时,效率是一个必须的

好的,为了解决上述问题,我最终编写了自己的代码。因此,我希望其他人也能发现它很有用,而不是仅仅求助于使用集合(拜托,你为什么要这么做?)

我想指出的是,示例代码使用的是vargargs语法(这是一个测试,因此使用它是一种有趣的方式),但是您显然可以只传递一个数组对象


另外,我必须补充一点,在对反射性能影响敏感的环境(如Android)上使用这种方法时,需要小心,因为在运行时使用反射(java.lang.reflect.newInstance(…)创建新数组。另一方面,如果您使用集合的toArray(T[])方法,并且传递的数组的大小不足以容纳所有集合元素(在这种情况下,在运行时分配一个新数组,就像我的代码一样),那么同样的情况也适用,因此,如果您以我所说的方式使用该方法,那么这段代码可能并不代表问题(在任何情况下,您都可以轻松地更改此代码以满足您的需要)。

数组的速度并不是比集合快很多,有些集合只是数组的包装器,因此您只需获得最快的速度即可

回到您的案例,我认为您可以使用
数组。asList
(由您的数组支持的列表)或
ImmutableList
(如果您不需要不断增长的数组)任何适合您的东西,但不要使用数组。第一个迹象是您必须编写不必要的代码(您的答案以及将来的更多代码)根据我的经验,这是不值得的


Java是一种更高层次的语言,出于种种原因,这种微小的优化最好留给Java来完成。但即便如此,如果您仍然有疑问,我建议您编写一个微型基准测试来验证您的假设。

泛型和数组不配合得很好。为什么您首先要使用数组而不是Lists?这就是你应该做的:更喜欢集合而不是数组。是的,不幸的是,在这种情况下我确实需要使用数组,而且在转换数组时我需要效率(可以是任何类型)。使用集合可以提高效率,因为它可以避免副本。Guava完全是关于集合的,而且,好吧,你在Guava中找不到你想要的方法。但是没有任何东西禁止你编写包含问题中发布的代码的包装。你可以创建一个列表,它只是另一个列表的视图。你不能使用数组。唯一的选项是创建副本。这就是为什么集合可以更快。通过避免副本。例如:
List listOfStrings=List.transform(listOfIntegers,i->i.toString())
是从列表创建的列表,不创建任何副本。这在数组中是不可能的。不能创建字符串[]数组,它是整数[]数组的视图。我从来没有说过数组比集合快得多(也许你想引用我的话?),我只是说,在特定条件下,没有什么比数组更有效。另一方面,我的问题不需要两个世界中的最佳,因为我的问题只存在于一个世界中(我在我的帖子中添加了进一步的澄清,所以你可能想检查一下).@RodrigoQuesada,在本机C中,我相信你是对的,没有什么能比数组访问更好。在Java等托管语言中,使用JIT,我不太确定。我建议你不要轻视微基准测试——它们是沟通此类问题的完美工具。@RodrigoQuesada,但我相信你的想法是错误的JVM中的数组实际上与C中的数组非常相似。在前者中,访问数组元素仍然需要通过JVM字节码——您不是直接使用指针访问底层内存空间。底层问题是您使用的是对象数组:在Java中,这最多意味着一个se存储在单个内存块中的一系列引用。这些引用可能指向其他任何地方,这意味着从快速数组迭代中获得的任何好处都会受到堆访问的阻碍。
public static <A, B> B[] transform(Class<B> theReturnedValueType, Function<A, B> functionToApply, A... theValues) {

    B[] transformedValues = (B[]) Array.newInstance(theReturnedValueType, theValues.length);

    for (int i = 0; i < theValues.length; i++) {
        transformedValues[i] = functionToApply.apply(theValues[i]);
    }

    return transformedValues;
}
Integer[] returnedNumbers = ArrayTransformer.transform(Integer.class, squareNumberFunction, 1, 2, 3);

assertThat(returnedNumbers).isEqualTo(new Integer[]{1, 4, 9});