如果用户已经给定了,如何停止将用户给定的对象添加到数组列表中?
How to stop adding objects given by the user to an arraylist if they already gave it?
这是class
public class Book {
private String name;
private int publicationYear;
public Book(String name, int publicationYear) {
this.name = name;
this.publicationYear = publicationYear;
}
public boolean equals(Book compared) {
if (this == compared) {
return true;
}
if (!(compared instanceof Book)) {
return false;
}
Book comparedBook = (Book) compared;
if (this.name.equals(comparedBook.name)
&& this.publicationYear == comparedBook.publicationYear) {
return true;
}
return false;
}
}
我尝试在主程序中这样做
while (true) {
System.out.println("Name (empty will stop):");
String name = scanner.nextLine();
if (name.isEmpty()) {
break;
}
System.out.println("Publication year:");
int publicationYear = Integer.valueOf(scanner.nextLine());
Book book = new Book(name, publicationYear);
if (!(books.contains(book))) {
books.add(book);
}
因此,如果用户一直提供同名同年份的书,程序仍会将它们添加到列表中
您无法更改 Object.equals(Object)
的签名。
您应该使用 Oracle 的 @Override
annotation to catch this kind of error. See tutorial。
@Override
public boolean equals(Object compared) {
if (this == compared) {
return true;
}
if (!(compared instanceof Book)) {
return false;
}
Book comparedBook = (Book) compared;
if (this.name.equals(comparedBook.name)
&& this.publicationYear == comparedBook.publicationYear) {
return true;
}
return false;
}
是正确的和明智的。
或者,在 Java 16+ 中,您可以通过让 Java 处理 equals
.[=28 的实现来避免错误编写 equals
方法的问题=]
record
Java 16 带来了 records 功能。记录是编写 class 的一种简短方式,其主要目的是透明且不可变地传递数据。您只需声明每个成员字段的类型和名称。编译器隐式创建构造函数、getter、equals
& hashCode
和 toString
.
顺便说一下,Java 提供了 class 来表示年份:java.time.Year
.
public record Book ( String title , Year published ) {}
equals
等隐式方法被实现以考虑每个成员字段。
new Book( "Free To Choose" , Year.of( 1990 ) )
.equals(
new Book( "The Foundation Trilogy" , Year.of( 1974 ) )
)
false
您可以在本地、嵌套或单独定义一条记录。在 Java 16 及更高版本中,枚举和接口也是如此。
Set
要在自动消除重复项的同时收集对象,请使用 Set
实现。
Set< Book > books = new HashSet<>() ;
books.add( new Book( "Free To Choose" , Year.of( 1990 ) ) ) ;
books.add( new Book( "Free To Choose" , Year.of( 1990 ) ) ) ; // Duplicate! Not added, because a set does not allow duplicates.
books.add( new Book( "The Foundation Trilogy" , Year.of( 1974 ) ) ) ;
Interrogate for the size。你会发现尺寸是两个而不是三个。
这是class
public class Book {
private String name;
private int publicationYear;
public Book(String name, int publicationYear) {
this.name = name;
this.publicationYear = publicationYear;
}
public boolean equals(Book compared) {
if (this == compared) {
return true;
}
if (!(compared instanceof Book)) {
return false;
}
Book comparedBook = (Book) compared;
if (this.name.equals(comparedBook.name)
&& this.publicationYear == comparedBook.publicationYear) {
return true;
}
return false;
}
}
我尝试在主程序中这样做
while (true) {
System.out.println("Name (empty will stop):");
String name = scanner.nextLine();
if (name.isEmpty()) {
break;
}
System.out.println("Publication year:");
int publicationYear = Integer.valueOf(scanner.nextLine());
Book book = new Book(name, publicationYear);
if (!(books.contains(book))) {
books.add(book);
}
因此,如果用户一直提供同名同年份的书,程序仍会将它们添加到列表中
您无法更改 Object.equals(Object)
的签名。
您应该使用 Oracle 的 @Override
annotation to catch this kind of error. See tutorial。
@Override
public boolean equals(Object compared) {
if (this == compared) {
return true;
}
if (!(compared instanceof Book)) {
return false;
}
Book comparedBook = (Book) compared;
if (this.name.equals(comparedBook.name)
&& this.publicationYear == comparedBook.publicationYear) {
return true;
}
return false;
}
或者,在 Java 16+ 中,您可以通过让 Java 处理 equals
.[=28 的实现来避免错误编写 equals
方法的问题=]
record
Java 16 带来了 records 功能。记录是编写 class 的一种简短方式,其主要目的是透明且不可变地传递数据。您只需声明每个成员字段的类型和名称。编译器隐式创建构造函数、getter、equals
& hashCode
和 toString
.
顺便说一下,Java 提供了 class 来表示年份:java.time.Year
.
public record Book ( String title , Year published ) {}
equals
等隐式方法被实现以考虑每个成员字段。
new Book( "Free To Choose" , Year.of( 1990 ) )
.equals(
new Book( "The Foundation Trilogy" , Year.of( 1974 ) )
)
false
您可以在本地、嵌套或单独定义一条记录。在 Java 16 及更高版本中,枚举和接口也是如此。
Set
要在自动消除重复项的同时收集对象,请使用 Set
实现。
Set< Book > books = new HashSet<>() ;
books.add( new Book( "Free To Choose" , Year.of( 1990 ) ) ) ;
books.add( new Book( "Free To Choose" , Year.of( 1990 ) ) ) ; // Duplicate! Not added, because a set does not allow duplicates.
books.add( new Book( "The Foundation Trilogy" , Year.of( 1974 ) ) ) ;
Interrogate for the size。你会发现尺寸是两个而不是三个。