Java:比串联更好的比较两组数字的方法
情况是这样的:我想基于两个不同的ID测试两个对象的唯一性。例如:Java:比串联更好的比较两组数字的方法,java,algorithm,set,object-comparison,Java,Algorithm,Set,Object Comparison,情况是这样的:我想基于两个不同的ID测试两个对象的唯一性。例如: // Note I'm using JSON notation to keep things simple; the actual code // is with Java Objects // OBJECT A { main_id: 0, id_a: 123, id_b: 456 } // OBJECT B { main_id: 1, id_a: 123, id_b: 456
// Note I'm using JSON notation to keep things simple; the actual code
// is with Java Objects
// OBJECT A
{
main_id: 0,
id_a: 123,
id_b: 456
}
// OBJECT B
{
main_id: 1,
id_a: 123,
id_b: 456
}
// OBJECT C
{
main_id: 2,
id_a: 123,
id_b: 789
}
在本例中,对象A和B是相同的,因为id_A
和id_B
是相同的,而对象C是不同的
在代码中确定这一点,我计划将ID都转换为字符串,并将它们与中间的分隔符(例如,<代码>){IDA},{IDYB}“<代码> >连接起来,然后将它们添加到<代码> SET>代码>中以测试其唯一性。
我的问题是,有更好的方法吗?(我说的更好,是指效率更高和/或更低)请看,这里我重写equals()和hashcode(),以确保Person对象“name”字段的唯一性
public class SetObjectEquals {
Person p1 = new Person("harley");
Person p2 = new Person("harley");
public void method1() {
Set<Person> set = new HashSet<Person>();
set.add(p1);
set.add(p2);
System.out.println(set);
}
public static void main(String[] args) {
SetObjectEquals obj = new SetObjectEquals();
obj.method1();
}
}
class Person {
String name;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
Person(String name) {
this.name = name;
}
}
公共类SetObjectEquals{
人员p1=新人(“哈雷”);
人员p2=新人(“哈雷”);
公共无效方法1(){
Set=newhashset();
集合。添加(p1);
集合。添加(p2);
系统输出打印项次(套);
}
公共静态void main(字符串[]args){
SetObjectEquals obj=新的SetObjectEquals();
对象方法1();
}
}
班主任{
字符串名;
@凌驾
公共int hashCode(){
最终整数素数=31;
int结果=1;
result=prime*result+((name==null)?0:name.hashCode();
返回结果;
}
@凌驾
公共布尔等于(对象obj){
if(this==obj)
返回true;
if(obj==null)
返回false;
如果(getClass()!=obj.getClass())
返回false;
人员其他=(人员)obj;
if(name==null){
if(other.name!=null)
返回false;
}如果(!name.equals(other.name))
返回false;
返回true;
}
Person(字符串名称){
this.name=名称;
}
}
看到这一点,这里我重写了equals()和hashcode(),以确保Person对象的“name”字段的唯一性
public class SetObjectEquals {
Person p1 = new Person("harley");
Person p2 = new Person("harley");
public void method1() {
Set<Person> set = new HashSet<Person>();
set.add(p1);
set.add(p2);
System.out.println(set);
}
public static void main(String[] args) {
SetObjectEquals obj = new SetObjectEquals();
obj.method1();
}
}
class Person {
String name;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
Person(String name) {
this.name = name;
}
}
公共类SetObjectEquals{
人员p1=新人(“哈雷”);
人员p2=新人(“哈雷”);
公共无效方法1(){
Set=newhashset();
集合。添加(p1);
集合。添加(p2);
系统输出打印项次(套);
}
公共静态void main(字符串[]args){
SetObjectEquals obj=新的SetObjectEquals();
对象方法1();
}
}
班主任{
字符串名;
@凌驾
公共int hashCode(){
最终整数素数=31;
int结果=1;
result=prime*result+((name==null)?0:name.hashCode();
返回结果;
}
@凌驾
公共布尔等于(对象obj){
if(this==obj)
返回true;
if(obj==null)
返回false;
如果(getClass()!=obj.getClass())
返回false;
人员其他=(人员)obj;
if(name==null){
if(other.name!=null)
返回false;
}如果(!name.equals(other.name))
返回false;
返回true;
}
Person(字符串名称){
this.name=名称;
}
}
如果要使用HashSet
,可以覆盖hashCode
和equals
以独占地查看这两个成员
散列代码:(31
只是Java中常用的散列元素)
等于:(显然,您需要添加检查和类型转换的实例)
如果您不想将这些函数绑定到该类,因为它在其他地方的使用方式不同,但您仍然想使用HashSet
,您可以考虑:
- 创建一个要存储在集合中的中间类,该类将包含您的类作为成员,并适当地实现上述方法
- 使用字符串方法
- 使用
HashSet
-Point
对于非协调目的并不理想,因为成员的名称仅为x
和y
,但我发现这样一个类很有用,至少对于非生产代码是如此
或者,如果你想使用树集
,你可以让你的类实现compariable
(覆盖comparieto
),或者为树集
提供一个比较器
,两者主要在一个id上进行比较,其次在另一个id上进行比较
基本思想如下所示:
if (objectA.id_a != objectB.id_a)
return Integer.compare(objectA.id_a, objectB.id_a);
return Integer.compare(objectA.id_b, objectB.id_b);
如果要使用HashSet
,可以重写hashCode
和equals
以独占地查看这两个成员
散列代码:(31
只是Java中常用的散列元素)
等于:(显然,您需要添加检查和类型转换的实例)
如果您不想将这些函数绑定到该类,因为它在其他地方的使用方式不同,但您仍然想使用HashSet
,您可以考虑:
- 创建一个要存储在集合中的中间类,该类将包含您的类作为成员,并适当地实现上述方法
- 使用字符串方法
- 使用
HashSet
-Point
对于非协调目的并不理想,因为成员的名称仅为x
和y
,但我发现这样一个类很有用,至少对于非生产代码是如此
或者,如果你想使用树集
,你可以让你的类实现compariable
(覆盖comparieto
),或者为树集
提供一个比较器
,两者主要在一个id上进行比较,其次在另一个id上进行比较
基本思想如下所示:
if (objectA.id_a != objectB.id_a)
return Integer.compare(objectA.id_a, objectB.id_a);
return Integer.compare(objectA.id_b, objectB.id_b);
我不确定这是否更有效或更不麻烦。您可以使用
public interface CompositeIdEntity {
long getIdA();
long getIdB();
}
public class Entity implements CompositeIdEntity {
private final long mainId;
private final long idA;
private final long idB;
public Entity(long mainId, long idA, long idB) {
this.mainId = mainId;
this.idA = idA;
this.idB = idB;
}
@Override
public long getIdA() {
return idA;
}
@Override
public long getIdB() {
return idB;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (mainId ^ (mainId >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Entity other = (Entity) obj;
if (mainId != other.mainId)
return false;
return true;
}
@Override
public String toString() {
return "Entity [mainId=" + mainId + ", idA=" + idA + ", idB=" + idB
+ "]";
}
}
public class CompositeIdWrapper {
private final CompositeIdEntity compositeIdEntity;
public CompositeIdWrapper(CompositeIdEntity compositeIdEntity) {
this.compositeIdEntity = compositeIdEntity;
}
public CompositeIdEntity getCompositeIdEntity() {
return compositeIdEntity;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ (int) (compositeIdEntity.getIdA() ^ (compositeIdEntity
.getIdA() >>> 32));
result = prime * result
+ (int) (compositeIdEntity.getIdB() ^ (compositeIdEntity
.getIdB() >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
CompositeIdWrapper other = (CompositeIdWrapper) obj;
if (compositeIdEntity.getIdA() != other.compositeIdEntity.getIdA())
return false;
if (compositeIdEntity.getIdB() != other.compositeIdEntity.getIdB())
return false;
return true;
}
}
import java.util.HashSet;
import java.util.Set;
public class Test {
public static void main(String[] args) {
Entity en1 = new Entity(0, 123, 456);
Entity en2 = new Entity(1, 123, 456);
Entity en3 = new Entity(2, 123, 789);
Entity en4 = new Entity(2, 123, 456);
Entity en5 = new Entity(1, 123, 789);
// Set based on main id
Set<Entity> mainIdSet = new HashSet<>();
mainIdSet.add(en1);
mainIdSet.add(en2);
mainIdSet.add(en3);
mainIdSet.add(en4);
mainIdSet.add(en5);
System.out.println("Main id set:");
for (Entity entity : mainIdSet) {
System.out.println(entity);
}
// Set based on ida, idb
Set<CompositeIdWrapper> compositeIdSet = new HashSet<>();
compositeIdSet.add(new CompositeIdWrapper(en1));
compositeIdSet.add(new CompositeIdWrapper(en2));
compositeIdSet.add(new CompositeIdWrapper(en3));
compositeIdSet.add(new CompositeIdWrapper(en4));
compositeIdSet.add(new CompositeIdWrapper(en5));
System.out.println("Composite id set:");
for (CompositeIdWrapper wrapped : compositeIdSet) {
System.out.println(wrapped.getCompositeIdEntity());
}
}
}
Main id set:
Entity [mainId=1, idA=123, idB=456]
Entity [mainId=2, idA=123, idB=789]
Entity [mainId=0, idA=123, idB=456]
Composite id set:
Entity [mainId=0, idA=123, idB=456]
Entity [mainId=2, idA=123, idB=789]