ArrayList中可能匹配项的Java迭代
我的问题是关于迭代和性能。让我们考虑以下情况:ArrayList中可能匹配项的Java迭代,java,performance,arraylist,Java,Performance,Arraylist,我的问题是关于迭代和性能。让我们考虑以下情况: public class Car { private String name; private int type; private int horsePower; String getKey() { return type + "_" + horsePower; } private final int NUM_OF_CARS = 50000; public void t
public class Car {
private String name;
private int type;
private int horsePower;
String getKey() {
return type + "_" + horsePower;
}
private final int NUM_OF_CARS = 50000;
public void test() {
List<Car> cars = new ArrayList<Car>(NUM_OF_CARS);
for (int i = 0; i < NUM_OF_CARS; i++) {
Car c = new Car();
if (i == 0 || i == 176 || i == 895 || i == 1500 || i == 4600) {
c.name = "Audi A4 " + i;
c.type = 1;
c.horsePower = 200;
} else {
c.name = "Default";
c.type = 2 + i;
c.horsePower = 201;
}
cars.add(c);
}
// Matches should contain all Audi's since they have same type and horse
// power
long time = SystemClock.currentThreadTimeMillis();
HashMap<String, List<Car>> map = new HashMap<String, List<Car>>();
for (Car c : cars) {
if (map.get(c.getKey()) != null) {
map.get(c.getKey()).add(c);
} else {
List<Car> list = new ArrayList<Car>();
list.add(c);
map.put(c.getKey(), list);
}
}
Iterator<Entry<String, List<Car>>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
if (iterator.next().getValue().size() == 1) {
iterator.remove();
}
}
Log.d("test", String.valueOf((SystemClock.currentThreadTimeMillis() - time)));
}
}
公车{
私有字符串名称;
私有int型;
私人马力;
字符串getKey(){
返回类型+马力;
}
私家车最终数量=50000辆;
公开无效测试(){
列表车辆=新阵列列表(车辆数量);
对于(int i=0;i
这是找到所有奥迪汽车的最有效方法吗
这花了我1700毫秒
谢谢。这取决于您进行迭代的原因。如果你真的需要参观每一辆底层汽车,那么你真的没有选择。但是,如果您正在寻找字符串的特定匹配,那么您可以考虑使用map。 为什么不尝试(<强> map < /强>):
基本上,它是一组哈希图的集合:
下面是一个例子:
Map<String, List<Car>> map = new HashMap<String, List<Car>>();
Map Map=newhashmap();
如果要查找字符串,应使用HashMap。否则,就我的想法而言,您无法避免这种类型的迭代。使用哈希集合:使用Object.hashCode()和Object.equals()优化搜索的HashSet。怎么做
必须定义MyClass.hashCode()和equals()的实现。hashCode()给出了对象的整数表示形式(您可以在这里做您想做的事情,但要以两个不同对象具有不同值的方式来做)
然后HashSet将对结果进行模运算。例如:如果HashSet大小为5000,它将进行模运算5000,并找到放置对象的索引。例如:如果hashCode()返回10252,则10252%5000=252。您的对象将被放入索引为252的数组中
最后,当您询问(我是否有“BMW x6”的实例)时,您询问的对象将调用其hashCode()方法,该方法将再次返回10252。HashSet将仅在252索引中有对象时进行搜索
如果有两个对象给出相同的hashCode,那么它们将通过equals()方法进行比较
我希望我的解释很清楚。简言之,实现hashCode和equals(),并尝试优化hashCode()的实现,以便在填充哈希集时获得时间
您可能还会对HashMap感兴趣,它在键使用哈希机制的地方存储键和值:因此您可以通过其键找到对象为什么嵌套for循环是件坏事?您是否分析并确定程序的这一部分是瓶颈?集合是ArrayList还是其他集合类/自定义收藏可以接受吗?它可能不是ArrayList,只需要容纳所有的汽车。告诉你更多关于你的要求。你知道你想找“奥迪”吗类型1和200马力?那么你不需要在循环中循环。或者你想找到所有类型和马力相同的车吗?在更新的测试代码中,所有匹配奥迪的车都有不同的名称和代码,但我不知道这是否是最快的实现。示例中的匹配标准是类型和马力rse power,很高兴匹配对象的名称可以相同,但也可以不同,但仍然可以通过类似的测试。我更新了我的问题,这样你就不会有错误的想法,我可以使用带有车名键的地图。我的回答仍然是正确的。如果你必须遍历整个列表,那么你就没有真正的choice。如果你担心查找时间,并且可以提前做一些索引,那么你应该使用地图。但过早优化是万恶之源,因此你可能担心一些并不重要的事情。比如说,匹配对象的名称可能不同,如奥迪A4、奥迪A4掀背车等,但它们是匹配的因为相同的类型和马力。我更愿意说,
HashMap
是Map
的一种类型。问题是我不能依赖这里的名字,比如宝马、奥迪和捷豹,但它们会与类型和马力相匹配。你说“HashSet”了吗?如果你使用任何“Set”在这个例子中,集合将只有一个对象和一个类型的马力。在这之后没有什么可以计算的!你的对象负责提供它自己的HASCODE()方法:所以你决定你是否考虑两个不同选项的汽车:你可以在你的HASCODE()中包括。方法对你来说很重要的字段:如果差异依赖于Car(型号、功率、颜色、版本),只需将这些值组合起来计算hashCode和equals方法(RaviH,你知道集合是如何工作的吗?你的问题很奇怪)