Java:使用equals覆盖从列表中删除对象

Java:使用equals覆盖从列表中删除对象,java,arraylist,java-8,Java,Arraylist,Java 8,注意:我必须使用Java 8 我试图从JavaArrayList中删除和添加对象,如下所示: private List<Point> points; [...] void addPoint(int x, int y) { Point newpoint = new Point(x, y); if (!points.contains(newpoint)) { points.add(new Point(x, y)); } else {

注意:我必须使用Java 8
我试图从Java
ArrayList
中删除和添加对象,如下所示:

private List<Point> points;

[...]

void addPoint(int x, int y) {
    Point newpoint = new Point(x, y);
    if (!points.contains(newpoint)) {
        points.add(new Point(x, y));
    } else {
        System.out.println("Error! Point already exists!");
    }
}

void removePoint(int x, int y) {
    Point newpoint = new Point(x, y);
    if (points.removeIf(n -> n.equals(newpoint))) {
        System.out.println("Point was removed!");
    } else {
        System.out.println("Error! Point does not exist!");
    }
}
私有列表点;
[...]
无效添加点(整数x,整数y){
点newpoint=新点(x,y);
如果(!points.contains(newpoint)){
点。添加(新点(x,y));
}否则{
System.out.println(“错误!点已存在!”);
}
}
无效删除点(整数x,整数y){
点newpoint=新点(x,y);
if(points.removeIf(n->n.equals(newpoint))){
System.out.println(“点被删除!”);
}否则{
System.out.println(“错误!点不存在!”);
}
}
是一个简单的对象,具有
x
y
int
等于
方法,如果提供的
对象具有相同的坐标,则返回

如您所见,我正在检查对象是否存在,然后添加它,在
removePoint
中,我使用
removeIf
(我认为这是次优的)从列表中删除该点。
那么,我如何通过覆盖
equals
方法正确解决这个问题,并且
removeIf
是否真正次优?

您可以覆盖EqualsAndHashCode方法,或者向Point.class添加一个方法,该方法比较给定的坐标,如

public boolean sameCoordinates(Point point){
  return this.x-point.getX()==0 && this.y-point.getY()==0
}
我在以前的项目中使用了removeIf,但我们用streams替代了它。一个原因是,removeIf可以在给定的列表上工作,Java可以通过引用调用工作。这迫使我们在调用removeIf之前复制每个方法中的列表,否则我们会通过程序更改它

另一个原因是,HashSet上的removeIf将更改该集,这意味着它将更改HashCode。Java safe anywhere指定此集合的哈希值。如果您想稍后使用这个集合,您将得到一个错误,因为Java不知道新的哈希值,而只知道旧的哈希值。我们花了一些时间才找到这个错误的根源

下面是一个如何使用流的小示例

 public static void main(String[] args){
    List<Integer> numberList = new ArrayList<>();
    numberList.add(1);
    numberList.add(2);
    numberList.add(3);
    numberList.add(4);
    numberList.add(5);
    numberList.add(6);

    List<Integer> evenNumbers = numberList.stream().filter(number -> number % 2 == 0).collect(Collectors.toList());
    System.out.println(evenNumbers);
publicstaticvoidmain(字符串[]args){
List numberList=new ArrayList();
数字列表。添加(1);
数字列表。添加(2);
数字列表。添加(3);
数字列表。添加(4);
数字列表。添加(5);
增加(6);
List evenNumbers=numberList.stream().filter(number->number%2==0).collect(collector.toList());
系统输出打印项次(偶数);

总而言之,我使用streams。我希望这对您有所帮助。

removeIf
是最有效的删除方法,如果您希望出现多次。如果您希望最多出现1次,请使用
remove
“和equals方法”我希望您也重写了
hashCode
。您真的需要
成为
列表
还是可以使用
来代替?对于这个用例,一个
HashSet
看起来很整洁。您确定,您不是在寻找一个有序的
吗?读取这些数据的查询是什么?如果需要的话保持元素的插入顺序,然后应使用
LinkedHashSet