我实际上有几个问题.
我有一个类Dog与以下实例字段:
private int id;
private int id_mother;
private int id_father;
private String name="";
private String owner="";
private String bDate="";
Run Code Online (Sandbox Code Playgroud)
我还有一个类Archive,它可以实例化Dog并将Dog对象放入ArrayList中.
我试图在Archive中编写一个方法,它接受一个整数作为ID并查看ArrayList,并返回包含该ID的对象.
private Dog getDog(int id){
Dog dog = new Dog();
int length=getSize();
int i=0;
dog=al.get(i);
i++;
while(dog.getId()!=id && i<length)
dog=al.get(i);
i++;
if(dog.getId()!=id)
dog=null;
return dog;
}//end getDog
Run Code Online (Sandbox Code Playgroud)
这种方法有两个问题(我使用的其他方法).首先它没有用,我看不出原因.我正在循环(可能)arraylist中的所有对象,因为在循环结束后,检查循环是否完成,因为它用完了要搜索的对象,或者因为它找到了具有给定ID的对象.其次,这似乎是一个非常耗时的过程.有什么方法可以加快速度吗?
Jon*_*Jon 44
假设您已经正确地为Dog编写了一个equals方法,根据Dog的id进行比较,返回列表中项目的最简单和最简单的方法如下.
if (dogList.contains(dog)) {
return dogList.get(dogList.indexOf(dog));
}
Run Code Online (Sandbox Code Playgroud)
这比其他方法的性能密集程度要低.在这种情况下,您根本不需要循环.希望这可以帮助.
PS你可以使用Apache Commons Lang为Dog编写一个简单的equals方法,如下所示:
@Override
public boolean equals(Object obj) {
EqualsBuilder builder = new EqualsBuilder().append(this.getId(), obj.getId());
return builder.isEquals();
}
Run Code Online (Sandbox Code Playgroud)
tpd*_*pdi 16
A while适用于之后的表达式或块while.
你没有一个区块,所以你的表情结束了 dog=al.get(i);
while(dog.getId()!=id && i<length)
dog=al.get(i);
Run Code Online (Sandbox Code Playgroud)
之后的一切只发生一次.
没有理由新建一只狗,因为你从来没有使用过新生的狗; 你立即将数组中的狗分配给你的狗参考.
如果需要获取键的值,则应使用Map,而不是Array.
编辑:这是为什么?
OP的评论:
关于不必制作狗的新实例的另一个问题.如果我只是从数组列表中取出对象的副本,那么我怎么能从数组列表中取出它而没有我放置它的对象?我刚刚注意到我没有将while循环括起来.
Java引用及其引用的对象是不同的东西.它们非常像C++引用和对象,尽管Java引用可以像C++指针一样重新指向.
结果是,Dog dog;或Dog dog = null给你一个指向没有对象的参考.new Dog() 创建一个可以指向的对象.
接下来,dog = al.get(i)意味着引用现在指向返回的狗引用al.get(i).理解,在Java中,永远不会返回对象,只引用对象(它们是内存中对象的地址).
你新建的狗的指针/参考/地址现在已经丢失,因为没有代码引用它,因为所指的对象被替换为所引用的对象al.get().最终,Java垃圾收集器将销毁该对象; 在C++中你会"泄露"内存.
结果是你确实需要创建一个可以引用Dog的变量; 你不需要创建一个狗new.
(实际上你不需要创建一个引用,因为你真正应该做的是返回一个Map从其get()函数返回的内容.如果Map没有在Dog上进行参数化,就像这样:Map<Dog>那么你'我需要从get中转换返回,但是你不需要引用:return (Dog) map.get(id);或者如果Map是参数化的,return map.get(id)那么一行是你的整个函数,并且它比在大多数情况下迭代一个数组要快. )
Rob*_*Rob 16
为了提高操作性能,如果您总是想要通过某个唯一标识符查找对象,那么您可以考虑使用Map<Integer,Dog>.这将按键提供恒定时间查找.您仍然可以使用地图迭代对象本身values().
一个快速的代码片段,可以帮助您入门:
// Populate the map
Map<Integer,Dog> dogs = new HashMap<Integer,Dog>();
for( Dog dog : /* dog source */ ) {
dogs.put( dog.getId(), dog );
}
// Perform a lookup
Dog dog = dogs.get( id );
Run Code Online (Sandbox Code Playgroud)
如果您在列表中执行多个相同性质的查找,这将有助于加快速度.如果您只是进行一次查找,那么无论如何都会产生相同的循环开销.
Jor*_*orn 13
你必须遍历整个数组,没有改变.但是,您可以更容易地做到这一点
for (Dog dog : list) {
if (dog.getId() == id) {
return dog; //gotcha!
}
}
return null; // dog not found.
Run Code Online (Sandbox Code Playgroud)
或没有新的for循环
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getId() == id) {
return list.get(i);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
138456 次 |
| 最近记录: |