如何在Java中过滤数组?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2082449/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 03:21:08  来源:igfitidea点击:

How to filter an array in Java?

javajava-mearraysvectorfilter

提问by hsmit

How can I filter an array in Java?

如何在 Java 中过滤数组?

I have an array of objects, for example cars:

我有一组对象,例如汽车:

Class:

班级:

public class Car{
    public int doors;
    public Car(int d){
        this.doors = d;
    }
}

Use:

用:

Car [] cars = new Cars[4];
cars[0] = new Car(3);
cars[1] = new Car(2);
cars[2] = new Car(4);
cars[3] = new Car(6);

Now I want to filter the array of cars, keeping only 4 doors and more:

现在我想过滤汽车数组,只保留 4 扇门或更多:

for(int i = 0; i<cars.length; i++){
    if(cars[i].doors > 4)
         //add cars[i] to a new array
    }
}

How should I do this?

我该怎么做?

Before I did it with a Vector:

在我用 Vector 做之前:

Vector subset = new Vector();
for(int i = 0; i<cars.length; i++){
    if(cars[i].doors > 4)
         //add cars[i] to a new array
        subset.addElement(cars[i]);
    }
}

And then I would make a new array with the size of the Vector. Then I would loop over the vector again and fill the new array. I know this is a very large procedure for something simple.

然后我将创建一个具有 Vector 大小的新数组。然后我会再次遍历向量并填充新数组。我知道对于简单的事情来说这是一个非常大的过程。

I'm using J2ME.

我正在使用 J2ME。

采纳答案by Kaleb Brasee

EDIT:saw that ArrayList is not in J2ME, but based on documentation, it does have a Vector. If that Vector class is different than J2SE Vector (as this documentation indicates), then perhaps the following code would work:

编辑:看到 ArrayList 不在 J2ME 中,但根据文档,它确实有一个 Vector。如果该 Vector 类与 J2SE Vector 不同(如本文档所示),那么下面的代码可能会起作用:

Vector carList = new Vector();
for(int i = 0; i<cars.length; i++){
    if(cars[i].doors > 4)
         carList.addElement(cars[i]);
    }
}
Car[] carArray = new Car[carList.size()];
carList.copyInto(carArray);

回答by notnoop

You can use System.arrayCopy():

您可以使用System.arrayCopy()

Car[] cars = ...
int length = cars.length < 4 ? cars.length() : 4;
Car filter = new Car[4];
System.arrayCopy(cars, 0, filter, 0, length);

UPDATE: System.arrayCopyis available in Java ME API, unlike Vector.subList(). Thanks for the correction.

更新:System.arrayCopyJava ME API 中可用,与 Vector.subList() 不同。谢谢指正。

回答by finnw

I can't see much wrong with your code. You could just stick with Vectors throughout though.

我看不出你的代码有什么问题。不过,您可以始终坚持使用 Vectors。

You could simplify the second part (where you copy the matching items into the new array) using Vector.copyInto(Object[]).

您可以使用 Vector.copyInto(Object[]) 简化第二部分(将匹配项复制到新数组中)。

回答by Joonas Pulakka

If you really need a plain array as the result, I think your way is the way to go: you don't know the number of resulting elements before you filter, and you can't construct a new array without knowing the number of elements.

如果你真的需要一个普通数组作为结果,我认为你的方法是要走的路:在过滤之前你不知道结果元素的数量,并且你不能在不知道元素数量的情况下构造一个新数组.

However, if you don't need thread-safety, consider using ArrayListinstead of a Vector. It ought to be somewhat faster. Then use ArrayList's toArraymethod to get the array.

但是,如果您不需要线程安全,请考虑使用ArrayList而不是Vector. 应该会快一些。然后使用ArrayList的toArray方法获取数组。

回答by Porculus

There's no direct way to remove elements from an array; its size is fixed. Whatever you do, you need to allocate a new array somehow.

没有直接的方法可以从数组中删除元素;它的大小是固定的。无论你做什么,你都需要以某种方式分配一个新数组。

If you want to avoid the minor memory overhead of allocating a Vector, another option would be to make two passes over your array. The first time, simply count the number of elements that you want to keep. Then allocate an array that size, and loop over your old array again, copying matching elements into the new array.

如果您想避免分配 a 的较小内存开销Vector,另一种选择是对数组进行两次传递。第一次,只需计算要保留的元素数量。然后分配一个该大小的数组,并再次遍历旧数组,将匹配的元素复制到新数组中。

回答by Bozho

You will need to create a new array anyway.

无论如何,您都需要创建一个新数组。

Vector vector = new Vector(array.length);

for (int i = 0; i < array.length; i++) {
    if (array[i].doors > 4) {
        vector.add(array[i]);
    }
}

Car[] result = new Car[vector.size()];
vector.copyInto(result);

This isn't quite efficient, though.

但是,这不是很有效。

回答by Rex Kerr

The most efficient way to do this--if the predicate you're filtering on is inexpensive and you're accessing it with a single thread--is usually to traverse the list twice:

执行此操作的最有效方法 - 如果您过滤的谓词成本低廉并且您使用单个线程访问它 - 通常是遍历列表两次:

public Car[] getFourDoors(Car[] all_cars) {
  int n = 0;
  for (Car c : all_cars) if (c.doorCount()==4) n++;
  Car[] cars_4d = new Car[n];
  n = 0;
  for (Car c : all_cars) if (c.doorCount()==4) cars_4d[n++] = c;
  return cars_4d;
}

This traverses the list twice and calls the test twice, but has no extra allocations or copying. The Vector-style methods traverse the list once, but allocates about twice the memory it needs (transiently) and copies every good element about twice. So if you are filtering a tiny fraction of the list (or performance isn't an issue, which very often it isn't), then the Vector method is good. Otherwise, the version above performs better.

这将遍历列表两次并调用测试两次,但没有额外的分配或复制。Vector 风格的方法遍历列表一次,但分配大约两倍于它需要的内存(瞬时)并复制每个好的元素大约两次。因此,如果您要过滤列表的一小部分(或者性能不是问题,通常不是),那么 Vector 方法就很好。否则,上面的版本性能更好。