Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 重写类外的Object#equals(Object)_Java_Equals - Fatal编程技术网

Java 重写类外的Object#equals(Object)

Java 重写类外的Object#equals(Object),java,equals,Java,Equals,使用list.contains(someObject)时,是否可以在本地重写Object#equals(Object) 示例: class SomeObject { ... private int id; private String name; @Overrdide public boolean equals(Object other){ ... return this.id == other.id; } }

使用
list.contains(someObject)
时,是否可以在本地重写
Object#equals(Object)

示例:

class SomeObject {
    ...
    private int id;
    private String name;

    @Overrdide
    public boolean equals(Object other){
         ...
         return this.id == other.id;
    }
}
int objectId = ... // Some event which passes me the attribute of an object but not the object itself
但是当我使用
list.contains(someObject)
时,如果我想要另一种类型的equals呢?例如,我想知道列表是否包含某个名称?是否可以“匿名”覆盖
Object#equals(Object)

更具体地解释我为什么需要它:

class SomeObject {
    ...
    private int id;
    private String name;

    @Overrdide
    public boolean equals(Object other){
         ...
         return this.id == other.id;
    }
}
int objectId = ... // Some event which passes me the attribute of an object but not the object itself
现在我有了
List someObjects
,我想知道这个列表是否包含一个带有
objectId
的对象,而不必对它进行迭代

我能想到的一个“解决方案”是使用
Map-mapping
,然后使用
someObject=mapping.get(objectId)


编辑:我的问题不是重复的,因为我特别要求覆盖
对象#等于(对象)

您可以对从列表中获得的流对象应用过滤器。过滤器接受一个谓词,您可以在其中设置条件。然后,您可以检查过滤后的流是否为空:

list.stream().filter(e -> e.name.equals(otherName)).findAny().isPresent()
您可以按如下方式使其可重用,例如:

private <T> boolean containsWithPredicate(List<T> list, Predicate<T> predicate) {
    return list.stream().filter(predicate).findAny().isPresent();
}
编辑:

class SomeObject {
    ...
    private int id;
    private String name;

    @Overrdide
    public boolean equals(Object other){
         ...
         return this.id == other.id;
    }
}
int objectId = ... // Some event which passes me the attribute of an object but not the object itself
有一种简单得多的方法可以实现与上面完全相同的功能,方法是只调用,而不是执行
filter
然后执行
findAny

list.stream().anyMatch(predicate);

您可以将
树集
与自定义的
比较器
一起使用,以实现所需的功能。它不使用
equals()
表示相等,而是考虑如果
compare()
返回
0
,则对象相等

假设我们希望所有长度相同的
字符串都相等:

TreeSet<String> set = new TreeSet(new Comparator<>() {
    public int compare(String o1, String o2) {
       return o1.length() - o2.length();
    }
}
set.add("asd");
set.contains("foo");    // Returns true
TreeSet集=新树集(新比较器(){
公共整数比较(字符串o1、字符串o2){
返回o1.length()-o2.length();
}
}
设置。添加(“asd”);
set.contains(“foo”);//返回true

这是一个有用的构造(也适用于
TreeMap
),当您需要在不同的时间为对象创建不同的“相等定义”时,同时仍然使用集合。

对于同一个类,没有办法让多个
相等。但是您可以对类进行子类化并重写
hashCode>()
equals()
,然后根据要使用的
equals
使用所需的实例


我必须说,我不喜欢这样做,
equals
方法应该得到很好的定义,在不同的场景中使用多个
equals
将非常混乱。如果需要两个不同的
equals
方法,我将使用完全不同的实现,而不是子类化。因此,我强烈建议您重新考虑您的设计。

不确定这是一个解决方案还是一个变通方法,因为我也可以使用for-each循环进行迭代。但这绝对是一种方法。@SklogW我认为这是一个解决方案。需要一个“
等于
”匿名方法,可以自定义,所以首先想到的是函数式编程(可以将筛选器的谓词作为参数传递)。它看起来也更容易阅读。@SklogW这是您实际想要做的。如果您不想创建一个新的
equals
方法,您需要检查列表是否包含基于特定参数的内容,为此您需要一个-,这实际上就是方法中的lambda。特别是因为一个新的equals意味着我会更改对象的标识。你的方法清楚地表明了我的意图。Thx!我有点惊讶,没有
findAny
接受谓词。LINQ中的等价物是,它有两个重载。一个接受谓词,另一个不接受。这样你就不必做
Where
Any
(或
filter
findAny
)作为两个不同的操作。这应该是,但这是collections API最糟糕的地方。您可以在许多地方使用自定义比较器,但您只能使用一个
等于
的概念。如果Java只有case类:-(使用比较器指定相等对集合和映射键有效(但会损害性能-操作变为O(logn),因为必须使用TreeMap而不是HashMap)。但这对列表没有帮助。应该可以使用自定义的相等概念与方法,如
indexOf
contains
等,但如果不创建包装类并根据需要重写等于,则不可能。这非常烦人。@SklogW列表有多大?如果您对顺序和一个属性不感兴趣如果多次查询,您可以使用特定于此属性的比较器对列表重新排序,然后检查
Collections.binarySearch(list,cmp)>=0
是否不重复,因为我专门询问了重写equals().复制是隐含的IMHO。但它仍然会给我一个列表,其中有一个关于什么是相等的或不相等的永久定义,对吗?如果我只想要某类相等的值一次怎么办?我可以更改比较器吗?例如,它会定义“什么是相等的”对于该集合。您可以编写
比较器
,以便它对不同的对象具有不同的逻辑,但它将更容易出错,您需要确保遵守
compare()
的合同。很好的建议。如果我需要不同的equals,那么可能是我的设计问题。我会考虑这个问题。@SklogW这是个好主意。想想其他可能使用你的程序的程序员,他们怎么知道要选择什么实现?
equals
应该定义得很好。这很有意义。我想我正在努力工作围绕着一个糟糕的设计。谢谢!