我目前被困在代码的特定部分。对于我的班级,我们将创建一列包含包含人员或货物的车厢的火车。我们使用泛型来定义棚车是否可以容纳人员或货物。然后我们将个人/货物装载到车厢上,如果它与车厢上已有的人具有相同的字符串"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);
}
}
现在,它适用于您的People
和Cargo
现在。。。对于奖励积分,由于您每次添加项目时都会对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;
}
}
}
请注意,这里有一个细微的差别。我们确保将item
与remove()
一起使用。这是因为remove()
依赖于默认情况下将使用对象的引用值的equals()
。item
和thing
比较相等,但它们是同一类的两个不同实例。通过向remove()
提供它知道从列表中删除该实例的item
。
更好的是,因为它更快并避免这种情况......使用binarySearch()
并通过索引删除!
public void unload(T thing){
int index = Collections.binarySearch(boxcar, thing);
if (index >=0) {
boxcar.remove(index);
}
}