如何解决contains with ObservableList() 总是返回 false
我在我的 JavaFX 代码中使用 ObservableList,我试图测试这个列表中是否存在一个对象,但它总是返回 false,即使对于那些已经存在的对象。 这是我的代码:
private ObservableList<OMission> UserMission = FXCollections.observableArrayList();
OMission OM1 = new OMission(1,"user_firstname","user_lastname");
UserMission.add(OM1);
if(UserMission.contains(new OMission(1,"user_lastname")){
System.out.println("true");}
else {
System.out.println("false");
}
我期待得到“真实”,但我总是得到错误
发生了什么?
解决方法
您可能忽略了为 set.seed(1)
df <- data.frame(
ID = 1:15,LATITUDE = c(42.6,42.5,42.3,42.8,42.4,41.4,41.6,41.8,43.7,47.3),LONGITUDE = c(-71.5,-71.6,-71.9,-71.0,-71.1,-71.2,-70.5,-70.3,-68.3),x1 = runif(15,min=0,max=1000),x2 = runif(15,x3 = runif(15,x4 = runif(15,x5 = runif(15,x6 = runif(15,x7 = runif(15,x8 = runif(15,max=1000) )
require(ape)
dists <- as.matrix(dist(cbind(df$LONGITUDE,df$LATITUDE)))
dists.inv <- 1/dists
diag(dists.inv) <- 0
#check
dists.inv[1:5,1:5]
#deal with the infinite values in the matrix
dists.inv[is.infinite(dists.inv)] <- 0
#calculate Moran's I
Moran.I(df$x1,dists.inv)
和 equals
实现关键的 Object
覆盖。
这个问题不是特定于 OpenJFX 类 hashCode
。执行比较的任何集合(列表、集合、映射等)都取决于您为至少 ObservableList
和可能的 equals
编写适当的覆盖。 (提示:始终覆盖两者或两者都不覆盖,不要单独覆盖。)
以下是使用修改后的代码版本的示例代码。顺便说一下,你缺少一个右括号。此外,如果您遵循 Java 命名约定,生活会更轻松。
为简洁起见,我们使用 Java 16+ 中的新 records 特性。记录是编写类的一种更简洁的方法,其主要目的是透明和不可变地通信数据。您只需要声明每个成员字段的类型和名称。编译器隐式创建构造函数、getter、hashCode
& equals
和 hashCode
。默认情况下,后三种方法会检查每个成员字段的值。
为简单起见,我们在本地声明了 toString
。您也可以声明它是嵌套的或单独的。
record
运行时。
世界你好!
真实
如果使用 Java 的早期版本,或者如果记录不适合您的情况,请编写类似于以下内容的类。注意方法 package work.basil.example;
import javafx.collections.*;
public class App {
public static void main ( String[] args ) {
System.out.println ( "Hello World!" );
App app = new App ();
app.demo ();
}
private void demo () {
record Person( int id,String firstName,String lastName ) { }
ObservableList < Person > UserMission = FXCollections.observableArrayList ();
Person p1 = new Person ( 1,"Alice","Anderson" );
UserMission.add ( p1 );
if ( UserMission.contains ( new Person ( 1,"Anderson" ) ) ) {
System.out.println ( "true" );
} else {
System.out.println ( "false" );
}
}
}
和 equals
。
hashCode
覆盖 package work.basil.example;
import java.util.Objects;
public final class Person {
private final int id;
private final String firstName;
private final String lastName;
public Person ( int id,String lastName ) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
public int id () { return id; }
public String firstName () { return firstName; }
public String lastName () { return lastName; }
@Override
public boolean equals ( Object obj ) {
if ( obj == this ) return true;
if ( obj == null || obj.getClass () != this.getClass () ) return false;
var that = ( Person ) obj;
return this.id == that.id &&
Objects.equals ( this.firstName,that.firstName ) &&
Objects.equals ( this.lastName,that.lastName );
}
@Override
public int hashCode () {
return Objects.hash ( id,firstName,lastName );
}
@Override
public String toString () {
return "Person[" +
"id=" + id + "," +
"firstName=" + firstName + "," +
"lastName=" + lastName + ']';
}
}
/equals
的问题已经多次讨论过。 Search to learn more。
在我写这篇文章的时候,Basil 同时更新了他的答案,以包含一些额外的信息。因此,此答案中重复了一些信息。请原谅这里的任何重复。我暂时保留这个答案。
为了补充 Basil 的回答,一些不同的解决方案是:
- 编写 equals 和 hashcode 的自定义实现。
对于 OMission,实施 equals(Object obj)
(最好也实施 hashCode()
)。
您最终会得到 Basil 示例答案中的代码。
您可以自己从头开始编写这些方法,但是,我不建议这样做。手动编写这些函数时很容易犯不必要的愚蠢错误。
- 使用 IDE 自动生成 equals 和 hashcode 的实现。
大多数 IDE 都有一个菜单项或快捷方式来自动生成这些方法(请参阅 how to do this in Idea)。这就是我通常生成这些函数的方式。如果我在类中添加或删除一个字段,那么我会删除之前自动生成的函数并自动生成新函数。
- 使用第 3 方库生成等号和哈希码。
第三方库,例如 Lombok,可用于自动生成方法。 Lombok 将通过 annotations 执行此操作,例如只需将注释 @EqualsAndHashcode
添加到您的类定义中即可。
- 让 OMission 成为记录而不是类。
如果可以将数据表示为不可变的 record 而不是类是合适的,那么这是推荐的方法。它不适用于所有数据类型。
默认情况下,记录实现了适当的 equals 和 hashcode 方法。
record OMission(
int missionNum,String firstname,String lastname
) {}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。