我目前停留在代码的特定部分。对于我的班级,我们要创建一个包含载有人或货物的箱子的火车。我们使用泛型来定义一个棚车是否可以容纳人或货物。然后我们将个人/货物装载到棚车上,如果它与已经在棚车上的人具有相同的字符串“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。为了澄清,对象ID是字符串。我有其他课程,但我只包括我认为必要的课程。如果您需要更多文件,我将很乐意为您提供。我已经被困在这几个小时了,非常感谢任何帮助!非常感谢你提前!
编辑:我尝试过使用Collections API中的contains()方法,但为什么不起作用?听起来它会完美运作。
答案 0 :(得分:1)
您必须为您的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;
}
和hashCode可以是这样的
public int hashCode(){
return 37*this.getId().hashCode();
}
答案 1 :(得分:0)
我认为问题在于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;
}
如果你重写equals方法,那么你也必须覆盖hashCode方法
答案 2 :(得分:0)
接受的答案对你的使用是好的,实际上可以用来测试相等性,但是考虑一下它确实会留下问题:因为你的Boxcar
类是Generic,这将依赖于任何它坚持实施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 class中提供了一个 - 正是这一点 - 它依赖于一个排序列表,其中包含实现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);
}
}