我们在开发中经常会用到集合,常用的有ArrayList,HashSet,TreeSet等等。当集合是String、Int等基本数据类型的时候我们可以通过集合的contains()方法来实现比对是否存在。
但是当我们集合放的是我们自定义的对象应该怎么办呢?两个对象都是new出来的,对于集合来说,是两个不同的引用,这个时候直接使用contains()方法则无法实现。因为我们需要把自定义的对象改造一下。
改造之前我们还是想看看改造之前的例子吧。
我们先定义一个自定义类 Person
public class Person {
private String Name;
private int age;
private int sex;
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
}
然后我们看下面这段代码,这段代码中,我们new了两个Person对象。属性值都是一摸一样的,其实这个时候应该是认为元素是重复得,但是由于我们是通过new出来的,因此其实HashSet是认为非重复元素,正常添加
Person person = new Person();
person.setName("P1");
person.setAge(10);
person.setSex(1);
Person person2 = new Person();
person2.setName("P1");
person2.setAge(10);
person2.setSex(1);
HashSet<Person> hashSet = new HashSet<>();
hashSet.add(person);
hashSet.add(person2);
//打印出来的结果是:hashSet: size 2
Log.d("2635", "hashSet: size " + hashSet.size());
因此,我们需要改造一下Person,我们设定,只要Name是相同的,我们就认为是同一个对象,所以我们需要重写equals()和hashCode()两个方法,代码如下
public class Person {
private String Name;
private int age;
private int sex;
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
@Override
public boolean equals(Object o) {
// 注释部分是原来的自带的模板判断逻辑,我们需要修改这部分来实现我们需要的功能,只要Name相同,就认为是同一个对象
// if (this == o) return true;
// if (!(o instanceof Person)) return false;
// Person person = (Person) o;
// return age == person.age && sex == person.sex && Objects.equals(Name, person.Name);
if (o == null) {
return false;
}
if (this == o) {
return true;
}
Person person = (Person) o;
if (person.getName().equals(this.getName())) {
return true;
}
return false;
}
@Override
public int hashCode() {
// 注释部分是原来的自带的模板判断逻辑,我们需要修改这部分来实现我们需要的功能,只要Name相同,就认为是同一个对象
// return Objects.hash(Name, age, sex);
return Objects.hash(Name);
}
}
改造之后,在运行上面的添加代码,就会发现,hashSet: size 1 ,也就是hashSet只会添加一个元素进去,只要Name这个属性是相同的,就认为是同一个属性。
题外话:HashSet是无法排序的,也就是说使用HashSet虽然可以去重,但是只能自然排序,那么一般我得做法是给对象添加一个时间值来排序,通过实现Comparable来实现,代码如下,代码我 为了方便,使用age字段来进行排序。
实际开发中,可能需要先进先出这种规则,那么我们就创建一个日期即可。
package com.himarking.dow.tables;
import android.util.Log;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Objects;
import java.util.concurrent.BlockingDeque;
public class Person implements Comparable{
private String Name;
private int age;
private int sex;
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
@Override
public boolean equals(Object o) {
// 注释部分是原来的自带的模板判断逻辑,我们需要修改这部分来实现我们需要的功能,只要Name相同,就认为是同一个对象
// if (this == o) return true;
// if (!(o instanceof Person)) return false;
// Person person = (Person) o;
// return age == person.age && sex == person.sex && Objects.equals(Name, person.Name);
if (o == null) {
return false;
}
if (this == o) {
return true;
}
Person person = (Person) o;
if (person.getName().equals(this.getName())) {
return true;
}
return false;
}
@Override
public int hashCode() {
// 注释部分是原来的自带的模板判断逻辑,我们需要修改这部分来实现我们需要的功能,只要Name相同,就认为是同一个对象
// return Objects.hash(Name, age, sex);
return Objects.hash(Name);
}
@Override
public int compareTo(Object o) {
if (!(o instanceof Person)) return -1;
Person p = (Person) o;
if (this.getAge()>((Person) o).getAge()){
return -1;
}else {
return 1;
}
}
}