如果用户已经提供了对象,如何停止将用户提供的对象添加到数组列表中? [关闭]
Posted
技术标签:
【中文标题】如果用户已经提供了对象,如何停止将用户提供的对象添加到数组列表中? [关闭]【英文标题】:How to stop adding objects given by the user to an arraylist if they already gave it? [closed] 【发布时间】:2021-09-08 10:26:17 【问题描述】:这是课
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);
因此,如果用户继续提供具有相同名称和年份的书,程序仍会将它们添加到列表中
【问题讨论】:
有什么问题? 列表确实是错误的工作工具; Set 是避免重复的更好方法。 【参考方案1】:Answer by Elliott Frisch 是正确而明智的。
或者,在 Java 16+ 中,您可以通过让 Java 处理 equals
的实现来避免错误编写 equals
方法的问题。
record
Java 16 带来了records 功能。记录是编写类的一种简短方式,其主要目的是透明且不可变地传递数据。您只需声明每个成员字段的类型和名称。编译器隐式创建构造函数、getter、equals
& hashCode
和 toString
。
顺便说一句,Java 提供了一个类来表示年份: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 ) )
)
假
您可以在本地、嵌套或单独定义记录。 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。您会找到 2 号而不是 3 号。
【讨论】:
【参考方案2】:您不能更改Object.equals(Object)
的签名。
您应该使用@Override
注释来捕获此类错误。请参阅 Oracle 的 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;
【讨论】:
以上是关于如果用户已经提供了对象,如何停止将用户提供的对象添加到数组列表中? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
如何在 GraphQL 突变/解析器中为每个用户创建和停止唯一的计时器