在在列表中加入一系列连续的短裤的基础上,我尝试生成一系列原始的短裤。事实证明,这比预期要困难得多。
Short[] range = IntStream.range(0, 500).mapToObj(value -> (short) value).toArray(Short[]::new)起了作用,但:
short[] range = IntStream.range(0, 500).mapToObj(value -> (short) value).toArray(short[]::new)生成了一个编译器错误:
method toArray in interface Stream<T> cannot be applied to given types;
required: IntFunction<A[]>
found: short[]::new
reason: inference variable A has incompatible bounds
equality constraints: short
upper bounds: Object
where A,T are type-variables:
A extends Object declared in method <A>toArray(IntFunction<A[]>)
T extends Object declared in interface Stream这似乎是两个问题的交集:
short提供实现。有什么想法吗?
发布于 2015-06-12 03:15:47
您可以考虑使用我的StreamEx库。它用额外的方法扩展了standand流。我的库的目标之一是更好地与旧代码进行互操作。特别是它有IntStreamEx.toShortArray()和IntStreamEx.of(short...)
short[] numbers = IntStreamEx.range(500).toShortArray();
short[] evenNumbers = IntStreamEx.of(numbers).map(x -> x*2).toShortArray();请注意,它仍然是int数字流。当调用toShortArray()时,它们将使用(short)强制转换操作自动转换为short类型,因此有可能发生溢出。所以要小心使用。
还有IntStreamEx.toByteArray()、IntStreamEx.toCharArray()和DoubleStreamEx.toFloatArray()。
发布于 2015-06-12 09:07:04
规范的方法是实现自定义Collector。
class ShortCollector {
public static Collector<Integer,ShortCollector,short[]> TO_ARRAY
=Collector.of(ShortCollector::new, ShortCollector::add,
ShortCollector::merge, c->c.get());
short[] array=new short[100];
int pos;
public void add(int value) {
int ix=pos;
if(ix==array.length) array=Arrays.copyOf(array, ix*2);
array[ix]=(short)value;
pos=ix+1;
}
public ShortCollector merge(ShortCollector c) {
int ix=pos, cIx=c.pos, newSize=ix+cIx;
if(array.length<newSize) array=Arrays.copyOf(array, newSize);
System.arraycopy(c.array, 0, array, ix, cIx);
return this;
}
public short[] get() {
return pos==array.length? array: Arrays.copyOf(array, pos);
}
}然后你就可以用它
short[] array=IntStream.range(0, 500).boxed().collect(ShortCollector.TO_ARRAY);缺点是Collector只适用于引用类型(因为Generics不支持原始类型),因此您必须求助于boxed(),并且收集器无法利用有关元素数量的信息(如果有可用的话)。因此,在原始数据流上,性能可能比toArray()差得多。
因此,一个追求更高性能的解决方案(我仅限于单线程情况)如下所示:
public static short[] toShortArray(IntStream is) {
Spliterator.OfInt sp = is.spliterator();
long l=sp.getExactSizeIfKnown();
if(l>=0) {
if(l>Integer.MAX_VALUE) throw new OutOfMemoryError();
short[] array=new short[(int)l];
sp.forEachRemaining(new IntConsumer() {
int ix;
public void accept(int value) {
array[ix++]=(short)value;
}
});
return array;
}
final class ShortCollector implements IntConsumer {
int bufIx, currIx, total;
short[][] buffer=new short[25][];
short[] current=buffer[0]=new short[64];
public void accept(int value) {
int ix = currIx;
if(ix==current.length) {
current=buffer[++bufIx]=new short[ix*2];
total+=ix;
ix=0;
}
current[ix]=(short)value;
currIx=ix+1;
}
short[] toArray() {
if(bufIx==0)
return currIx==current.length? current: Arrays.copyOf(current, currIx);
int p=0;
short[][] buf=buffer;
short[] result=new short[total+currIx];
for(int bIx=0, e=bufIx, l=buf[0].length; bIx<e; bIx++, p+=l, l+=l)
System.arraycopy(buf[bIx], 0, result, p, l);
System.arraycopy(current, 0, result, p, currIx);
return result;
}
}
ShortCollector c=new ShortCollector();
sp.forEachRemaining(c);
return c.toArray();
}你可以把它当作
short[] array=toShortArray(IntStream.range(0, 500));https://stackoverflow.com/questions/30790665
复制相似问题