比较通用项目?



我目前被困在代码的特定部分。对于我的班级,我们将创建一列包含包含人员或货物的车厢的火车。我们使用泛型来定义棚车是否可以容纳人员或货物。然后我们将个人/货物装载到车厢上,如果它与车厢上已有的人具有相同的字符串"ID",那么我们会记录错误并且不会加载该人员/货物。这就是我遇到麻烦的地方。我一辈子都想不通如何比较他们的"ID",看看他们是否相等。以下是我到目前为止的代码,

package proj5;
public class Person implements Comparable<Person> {
private String id;
private String name;
private int age;
public Person(String id, String name, int age){
this.id = id;
this.id = id;
this.name = name;
this.age = age;
}   
public Person(String id){
this.id = id;
}
public String getId(){
return id;
}
public int getAge(){
return age;
}
public String getName(){
return name;
}
public String toString(){
String str = "        " + "ID: " + id + "  " + " Name: " + name + "  " + " Age: " + age;
return str;
}
public int compareTo(Person p) {
int result = this.id.compareTo(p.getId());
return result;
}

}

package proj5;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
public class Boxcar<T extends Comparable<T>> {
private ArrayList<T> boxcar;
private int maxItems;
private int boxcarID;
public Boxcar(){
boxcar = new ArrayList<T>();
}
public void load(T thing){
for(int i = 0; i < boxcar.size(); i++){
if(boxcar.size() < maxItems && !boxcar.get(i).equals(thing)){
boxcar.add(thing);
System.out.println(boxcar.get(i));
}
else{
boxcar.remove(thing);
}
}
Collections.sort(boxcar);
}
public int getBoxcarId(){
return boxcarID;
}
public int getMaxItems(){
return maxItems;
}
public void setMaxItems(int i){
maxItems = i;
}
public void unload(T thing){
for(T item : boxcar){
if(item.equals(thing)){
boxcar.remove(item);
}
}
}
public List<T> getBoxcar(){
return boxcar;
}
public String toString(){
String str = "";
for(T item : boxcar){
str += item + "n";
}
return str;
}

}

问题出在我的加载函数上。我不知道如何比较他们的身份证。为澄清起见,对象 ID 是字符串。我还有其他课程,但我只包括我认为必要的课程。如果您需要更多文件,我很乐意提供。我已经坚持了几个小时,希望得到任何帮助!提前非常感谢!

编辑:我已经尝试使用集合API中的contains()方法,但为什么不起作用?听起来它会完美地工作。

你必须为你的类 Person 实现 equals 和 hashCode。

问题是boxcar.get(i).equals(thing)调用泛型相等,并且只比较引用。

所以泛型等于会看起来像。

public boolean equals(Object obj){
if (obj == null) return false;
if (obj == this) return true;
if (obj instanceof Person){
Person p = (Person) obj;
return p.getId().equals(this.getId());
}
return false;
}

哈希代码可以是这样的

public int hashCode(){
return 37*this.getId().hashCode();
}

我认为问题是因为boxcar = new ArrayList<T>();因为它可以包含 人员/货物。如果它包含所有人反对,那么你的代码就可以了。但是因为它也可以包含货物,所以它显示出问题。

所以你可以做的只是检查它的对象是否是人,然后只检查比较。

public boolean equals(Object obj){
if (obj instanceof Person){
Person p = (Person) obj;
return p.getId().equals(this.getId());
}
return true;
}

如果你覆盖等于方法,那么你还必须覆盖哈希代码方法以

接受的答案可以供您使用,并且实际上可用于测试相等性,但是考虑一下它确实留下了一个问题:因为您的Boxcar类是泛型的,这将依赖于它所持有的任何内容来实现equals()hashcode()。您的load()方法本身也有问题。

由于您可以使用<T extends Comparable<T>>限制泛型,因此您只需执行以下操作:

if (boxcar.get(i).compareTo(thing) == 0) {

检查相等性,因为compareTo()将返回完全匹配的0

不过,您的load()方法不正确;它遍历ArrayList并一遍又一遍地添加相同的东西。为了满足您发布的标准,它需要如下所示:

public void load(T thing) {
boolean found = false;
// Go through ArrayList and see if thing exists
for (int i = 0; i < boxcar.size(); i++){
if (boxcar.get(i).compareTo(thing) == 0) { 
System.out.println(thing + " already exists");
found = true;
break;
}
}
// If the thing didn't exist, add it, and sort the ArrayList    
if (!found) {
boxcar.add(thing);
System.out.println("Added " + thing);
Collections.sort(boxcar);
}
}

现在,它适用于您的PeopleCargo

现在。。。对于奖励积分,由于您每次添加项目时都会对ArrayList进行排序,因此您可以使用二叉搜索而不是线性搜索。方便的是,Java Collections 类中为此提供了一个 - 它依赖于一个包含实现Comparable的东西的排序列表:

public void load(T thing) {
// See if the thing exists. binarySearch returns an index if it's there
// or a negative number if it's not
if (Collections.binarySearch(boxcar, thing) >= 0) {
System.out.println(thing + " already exists");
} else {
boxcar.add(thing);
System.out.println("Added " + thing);
Collections.sort(boxcar);
}
}

编辑以添加由于注释:您还需要更改unload()方法。同样,我们使用compareTo()来检查平等性。也。。。一旦找到它,你就不会打破你的循环。因为我们知道load的工作方式不能有重复,并且您永远不想在循环访问列表时修改列表:

public void unload(T thing){
for(T item : boxcar){
if(item.compareTo(thing) == 0) {
boxcar.remove(item);
break;
}
}
}

请注意,这里有一个细微的差别。我们确保将itemremove()一起使用。这是因为remove()依赖于默认情况下将使用对象的引用值的equals()itemthing比较相等,但它们是同一类的两个不同实例。通过向remove()提供它知道从列表中删除实例的item

更好的是,因为它更快并避免这种情况......使用binarySearch()并通过索引删除!

public void unload(T thing){
int index = Collections.binarySearch(boxcar, thing);
if (index >=0) {
boxcar.remove(index);
}
}

相关内容

  • 没有找到相关文章