Java 如何从迭代器中获取int[]?
我有一个迭代器。。。实际上,它是一个Java 如何从迭代器中获取int[]?,java,collections,Java,Collections,我有一个迭代器。。。实际上,它是一个类对象,它接受一个访问者,并为它包含的SomeObjects的子集调用visit(),我必须实现Visitor,所以它执行如下操作: // somehow get all the Id's from each of the SomeObject that Thing lets me visit public int[] myIdExtractor(Thing thing) { SomeCollection c = new SomeCollection(
类对象
,它接受一个访问者
,并为它包含的SomeObject
s的子集调用visit()
,我必须实现Visitor
,所以它执行如下操作:
// somehow get all the Id's from each of the SomeObject that Thing lets me visit
public int[] myIdExtractor(Thing thing)
{
SomeCollection c = new SomeCollection();
thing.visitObjects(new Visitor<SomeObject>()
{
public void visit(SomeObject obj) { c.add(obj.getId()); }
}
);
return convertToPrimitiveArray(c);
}
效率和内存使用率值得关注。您可以使用List.toArray(T[]a)代替convertToPrimitiveArray:
ArrayList al=new ArrayList();
//填充铝
int[]值=新的int[al.size()];
al.toArray(数值);
考虑到您事先不知道结果集的大小,LinkedList可能比ArrayList稍好一些
如果性能确实是个问题,您最好自己管理int[],并在每次int[]增长时使用System.arraycopy();任何集合所需的从int到Integer的装箱/拆箱操作都可能会造成伤害
当然,与任何与性能相关的问题一样,在花太多时间进行优化之前,测试并确保它真的很重要。创建一个在数组中收集
int
s的类并不太困难(即使您没有使用为您提供此功能的库)
(免责声明:这是stackoverflow,我甚至还没有尝试编译这段代码。)您可以看看类似的处理方法。这是一个针对原语的集合框架。为了基准测试,我使用LFSR生成器编写了一个测试程序,以防止编译器优化测试数组。无法下载pjc,但我认为计时应该类似于Tom的
IntBuffer
类,它是目前为止的赢家。ByteArrayOutputStream方法的速度与我最初的ArrayList
方法大致相同。我在3GHz奔腾4上运行J2SE 6u13,大约有220个值,在JIT运行之后,IntBuffer方法比使用“健忘”集合的参考实现高出大约40毫秒(每项仅40纳秒!),该集合只存储visit()
的最后一个参数(因此编译器不会对其进行优化)。另外两种方法的速度约为300毫秒,约为8倍
编辑:我怀疑流方法的问题在于,可能存在我必须捕获的异常,但我不确定
(对于参数,运行PrimitiveArrayTest 1 2)
package com.example.test.collections;
导入java.io.ByteArrayInputStream;
导入java.io.ByteArrayOutputStream;
导入java.io.DataInputStream;
导入java.io.DataOutputStream;
导入java.io.IOException;
导入java.util.ArrayList;
导入java.util.Collections;
导入java.util.List;
公共类原语数组测试{
接口对象{
公共int getX();
}
界面访问者{
公共无效访问(SomeObject obj);
}
公共静态类PlainObject实现了SomeObject
{
私人INTX;
public int getX(){返回this.x;}
公共void setX(int x){this.x=x;}
}
公共静态类事物
{
/*这是一个LFSR
*看http://en.wikipedia.org/wiki/Linear_feedback_shift_register
*及http://www.ece.cmu.edu/~koopman/lfsr/index.html
*/
私人和国家;
最终静态专用整数掩码=0x80004;
私有void_next()
{
this.state=(this.state>>>1)
^(((此状态&1)和掩码);
}
公共事物(int state){this.state=state;}
public void setState(int state){this.state=state;}
公共访客(访客v,int终止点)
{
PlainObject obj=新的PlainObject();
while(this.state!=终止点)
{
obj.setX(本州);
v、 访问(obj);
_next();
}
}
}
静态公共抽象类收集器实现访问者
{
抽象公共集合();
抽象公共int[]getCollection();
public int[]extractX(Thing-Thing,int-startState,int-endState)
{
initCollection();
设置状态(开始状态);
被邀请的访客(这个,结束状态);
返回getCollection();
}
公共void doit(Thing-Thing,int-startState,int-endState)
{
System.out.printf(“%s.doit(thing,%d,%d):\n”,
getClass().getName(),
startState,
终态);
long l1=System.nanoTime();
int[]result=extractX(事物、开始状态、结束状态);
long l2=System.nanoTime();
StringBuilder sb=新的StringBuilder();
sb.append(String.format(“%d个值以%.4f毫秒计算”),
结果:长度(l2-l1)*1e-6);
int N=3;
如果(结果长度0)
某人加上(“,”);
某人追加(结果[i]);
}
某人加上(“]”);
}
其他的
{
int sz=result.length;
sb.append(字符串格式(“[%d,%d,%d..%d,%d]”,
结果[0],结果[1],结果[2],
结果[sz-3],结果[sz-2],结果[sz-1]);
}
System.out.println(sb.toString());
}
}
静态公共类收集器0扩展了收集器
{
int-lastint=0;
@重写公共int[]getCollection(){返回新int[]{lastint};}
@重写公共void initCollection(){}
@重写公共void访问(SomeObject obj){lastint=obj.getX();}
}
静态公共类收集器1扩展了收集器
{
final private List ints=new ArrayList();
@重写公共int[]getCollection(){
int N=th
public int[] convertToPrimitiveArray(List<Integer> ints)
{
int N = ints.size();
int[] array = new int[N];
int j = 0;
for (Integer i : ints)
{
array[j++] = i;
}
return array;
}
ArrayList<int> al = new ArrayList<int>();
// populate al
int[] values = new int[al.size()];
al.toArray(values);
public class IntBuffer {
private int[] values = new int[10];
private int size = 0;
public void add(int value) {
if (!(size < values.length)) {
values = java.util.Arrays.copyOf(values, values.length*2);
}
values[size++] = value;
}
public int[] toArray() {
return java.util.Arrays.copyOf(values, size);
}
}
final ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
final DataOutputStream out = new DataOutputStream(byteOut);
...
out.writeInt(value);
...
out.flush();
final byte[] bytes = byteOut.toByteArray();
final int[] ints = new int[bytes.length/4];
final ByteArrayInputStream byteIn = new ByteArrayInputStream(bytes);
final DataInputStream in = new DataOutputStream(byteIn);
for (int ct=0; ct<ints.length; ++ct) {
ints[ct] = in.readInt();
}
package com.example.test.collections;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class PrimitiveArrayTest {
interface SomeObject {
public int getX();
}
interface Visitor {
public void visit(SomeObject obj);
}
public static class PlainObject implements SomeObject
{
private int x;
public int getX() { return this.x; }
public void setX(int x) { this.x = x; }
}
public static class Thing
{
/* here's a LFSR
* see http://en.wikipedia.org/wiki/Linear_feedback_shift_register
* and http://www.ece.cmu.edu/~koopman/lfsr/index.html
*/
private int state;
final static private int MASK = 0x80004;
private void _next()
{
this.state = (this.state >>> 1)
^ (-(this.state & 1) & MASK);
}
public Thing(int state) { this.state = state; }
public void setState(int state) { this.state = state; }
public void inviteVisitor(Visitor v, int terminationPoint)
{
PlainObject obj = new PlainObject();
while (this.state != terminationPoint)
{
obj.setX(this.state);
v.visit(obj);
_next();
}
}
}
static public abstract class Collector implements Visitor
{
abstract public void initCollection();
abstract public int[] getCollection();
public int[] extractX(Thing thing, int startState, int endState)
{
initCollection();
thing.setState(startState);
thing.inviteVisitor(this, endState);
return getCollection();
}
public void doit(Thing thing, int startState, int endState)
{
System.out.printf("%s.doit(thing,%d,%d):\n",
getClass().getName(),
startState,
endState);
long l1 = System.nanoTime();
int[] result = extractX(thing,startState,endState);
long l2 = System.nanoTime();
StringBuilder sb = new StringBuilder();
sb.append(String.format("%d values calculated in %.4f msec ",
result.length, (l2-l1)*1e-6));
int N = 3;
if (result.length <= 2*N)
{
sb.append("[");
for (int i = 0; i < result.length; ++i)
{
if (i > 0)
sb.append(", ");
sb.append(result[i]);
}
sb.append("]");
}
else
{
int sz = result.length;
sb.append(String.format("[%d, %d, %d... %d, %d, %d]",
result[0], result[1], result[2],
result[sz-3], result[sz-2], result[sz-1]));
}
System.out.println(sb.toString());
}
}
static public class Collector0 extends Collector
{
int lastint = 0;
@Override public int[] getCollection() { return new int[]{lastint}; }
@Override public void initCollection() {}
@Override public void visit(SomeObject obj) {lastint = obj.getX(); }
}
static public class Collector1 extends Collector
{
final private List<Integer> ints = new ArrayList<Integer>();
@Override public int[] getCollection() {
int N = this.ints.size();
int[] array = new int[N];
int j = 0;
for (Integer i : this.ints)
{
array[j++] = i;
}
return array;
}
@Override public void initCollection() { }
@Override public void visit(SomeObject obj) { ints.add(obj.getX()); }
}
static public class Collector2 extends Collector
{
/*
* adapted from http://stackoverflow.com/questions/1167060
* by Tom Hawtin
*/
private int[] values;
private int size = 0;
@Override public void visit(SomeObject obj) { add(obj.getX()); }
@Override public void initCollection() { values = new int[32]; }
private void add(int value) {
if (!(this.size < this.values.length)) {
this.values = java.util.Arrays.copyOf(
this.values, this.values.length*2);
}
this.values[this.size++] = value;
}
@Override public int[] getCollection() {
return java.util.Arrays.copyOf(this.values, this.size);
}
}
static public class Collector3 extends Collector
{
/*
* adapted from http://stackoverflow.com/questions/1167060
* by Tom Hawtin
*/
final ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
final DataOutputStream out = new DataOutputStream(this.byteOut);
int size = 0;
@Override public int[] getCollection() {
try
{
this.out.flush();
final int[] ints = new int[this.size];
final ByteArrayInputStream byteIn
= new ByteArrayInputStream(this.byteOut.toByteArray());
final DataInputStream in = new DataInputStream(byteIn);
for (int ct=0; ct<ints.length; ++ct) {
ints[ct] = in.readInt();
}
return ints;
}
catch (IOException e) { /* gulp */ }
return new int[0]; // failure!?!??!
}
@Override public void initCollection() { }
@Override public void visit(SomeObject obj) {
try {
this.out.writeInt(obj.getX());
++this.size;
}
catch (IOException e) { /* gulp */ }
}
}
public static void main(String args[])
{
int startState = Integer.parseInt(args[0]);
int endState = Integer.parseInt(args[1]);
Thing thing = new Thing(0);
// let JIT do its thing
for (int i = 0; i < 20; ++i)
{
Collector[] collectors = {new Collector0(), new Collector1(), new Collector2(), new Collector3()};
for (Collector c : collectors)
{
c.doit(thing, startState, endState);
}
System.out.println();
}
}
}