:非常大的数组:{o1,o2,o3,.,o100000}。在某些情况下,元素序列具有相同的字段值。我的意思是o1.getField()等于o2.getField()等于o3.getField()。让我们说,o1、o2和o3是相似的。
我想要的:对每个相似的元素子数组进行一些后置操作(例如。{o1, o2, o3},{o4, o5},.)
很重要:到期数组非常大,缓存(意味着将数组移动到另一个集合或复制其中的一部分)是不可接受的!
问题:,最优雅的方法是什么?
P.S. --我不需要对整个数组进行除法,只需要做一个postAction。我可以得到第一个{o1, o2, o3},制造postAction,而不是第二个,等等……
发布于 2014-05-19 16:10:43
我首先要挑战“数组不能复制”的前提。如果使用System.arrayCopy(),数组复制是非常快的!
下面是我编写的一个小示例程序,它创建、填充和复制一个包含100,000,000元素的数组。
public static void main(final String[] args) {
final Stopwatch stopwatch = new Stopwatch().start();
final String[] arr = new String[100_000_000];
Arrays.fill(arr, "foo");
final String[] arr2 = new String[arr.length];
System.arraycopy(arr, 0, arr2, 0, arr.length);
stopwatch.stop();
System.out.println(stopwatch.elapsed(MILLISECONDS));
}在我没有印象的机器上,这需要683毫秒。
如果这两个都不是“是”,我会使用一些复制解决方案。
发布于 2014-05-19 16:22:28
我假设您正在处理T类型的对象,并且有一个方法isSimilar(T o1, T o2)。我还假设您有一个类Processor<T>,它有一个方法postAction(Iterator<T> i) (可以适应postAction(Iterable<T> i))。
然后我会沿着这些路线走下去。这只是一个方向,不幸的是,我没有任何东西可以测试甚至编译。
public <T> void process(T[] array, Processor<T> p) {
for (int i=0, j=1; i<array.length && j<array.length; i=j, j++) {
while (j<array.length && isSimilar(array[i], array[j])) {
j++;
}
ArrayIterator<T> ai = new ArrayIterator<T>(array, i, j-1);
p.postAction(ai);
}
}
class ArrayIterator<T> implements Iterator<T> {
T[] array;
int current;
int end;
public ArrayIterator(T[] a, int s, int e) {
array = a;
current = s;
end = e;
}
public boolean hasNext() {
return current <= end;
}
public T next() {
return array[current++];
}
}如果postAction接受一个List或其他强制的集合,您可以创建这样一个由数组备份的集合,比如Arrays.asList(),但是它将是更多的锅炉板代码。如果postAction需要一个数组,我认为你必须复制.
发布于 2014-05-19 16:53:15
我们有这门课
public static class MisteriousItem {
public int oddlyFamiliarValue;
public MisteriousItem(int oddlyFamiliarValue) {
this.oddlyFamiliarValue = oddlyFamiliarValue;
}
}我们用它来放置数组:
Random rand = new Random();
MisteriousItem[] magicBox = new MisteriousItem[1_000];
for (int i = 0; i < magicBox.length; i++) {
magicBox[i] = new MisteriousItem(rand.nextInt(3));
}然后我们准备了很少的价值
List<Entry<Integer, String>> something;
something = new ArrayList<>();
MisteriousItem x = magicBox[0];
StringBuilder sb = new StringBuilder("{");
sb.append(x.oddlyFamiliarValue);
int id = 0;我知道你说过没有副本,但这不是一种超自然的东西,只是和熟悉的物体有关而已
现在我们迭代
for (int i = 1; i < magicBox.length; i++) {
MisteriousItem mi = magicBox[i];
if (mi.oddlyFamiliarValue == x.oddlyFamiliarValue) {
sb.append(",");
sb.append(id++);
} else {
sb.append("}");
something.add(new Entry<>(x.oddlyFamiliarValue, sb.toString()));
x = mi;
sb = new StringBuilder("{");
sb.append(id++);
}
}如您所见,我们接受第一个对象并开始处理,然后从第二个项开始对整个数组进行迭代,在执行任何操作之前,我们将检查它是否类似于以前的对象。然后,我们对比较的结果采取相应的行动。如果你正在寻找一些更优雅的方式,留下评论,说什么应该是不同的。
编辑
也许这是你想要的更多
int end=0;
int start= 1;
MisteriousItem x = magicBox[0];
for (int i = 1; i < magicBox.length; i++) {
MisteriousItem mi = magicBox[i];
if (mi.oddlyFamiliarValue == x.oddlyFamiliarValue) {
end++;
} else {
process(magicBox,start,end);
//process lost starting from start(inclusive) to end(exclusive)
start=i;
}
}https://stackoverflow.com/questions/23742058
复制相似问题