Java8 List去掉重复对象以及保证添加顺序
JAVA中List对象去除重复值,大致分为两种情况,一种是List、List这类,直接根据List中的值进行去重,另一种是List这种,List中存的是javabean对象,需要根据List中对象的某个值或某几个值进行比较去重。
一、去重
1、List、List对象去重复值
利用Set集合的特性:
Set<String> set = new LinkedHashSet<>();
set.addAll(list);
list.clear();
list.addAll(set);
通过JDK1.8新特性stream的distinct方法,可以直接处理:
List<String> list = list.stream().distinct().collect(Collectors.toList());
2、List<Student>中对象去重复值
这种的话,不能直接比较List中的对象,需要重写bean对象的equals和hashCode方法,然后通过进行去重,具体例子如下:
public class Student
private Long id;
private String name;
重写Student对象的equals()方法和hashCode()方法:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student Student = (Student) o;
if (!id.equals(Student.id)) return false;
return name.equals(Student.name);
}
@Override
public int hashCode() {
int result = id.hashCode();
result = 19 * result + name.hashCode();
return result;
}
List<Student> students = Arrays.asList(s1, s2, s3);
List<Student> studentsNew = new ArrayList<>();
// 去重
students.stream().forEach(
s -> {
if (!studentsNew.contains(s)) {
studentsNew.add(s);
}
}
);
List的contains()方法实际上是用对象的equals方法去比较
3、根据对象的属性去重
java8的stream流能完美解对象集合去重问题:
List<UserCar> list1 = new ArrayList();
UserCar userCar = new UserCar();
userCar.setId(1);
userCar.setCarNo("AA");
list1.add(userCar);
UserCar userCar1 = new UserCar();
userCar1.setId(2);
userCar1.setCarNo("AA");
list1.add(userCar1);
Person p1 = new Person(1, "11");
Person p2 = new Person(1, "22");
Person p3 = new Person(2, "11");
List<Person> persons = Arrays.asList(p1, p2, p3);
1、不使用java8
private List<UserCar> removeDupliByRecordId(List<UserCar> userCars) {
Set<UserCar> personSet = new TreeSet<UserCar>((o1, o2) -> o1.getRecordId().compareTo(o2.getRecordId()));
personSet.addAll(userCars);
return new ArrayList<UserCar>(personSet);
}
这也是大多数人第一想到的,借助 TreeSet 去重,其中 TreeSet 的其中一个构造函数接收一个排序的算法,同时这也会用到 TreeSet 的去重策略上。
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
2、第一种java8写法
List<Person> unique = persons.stream().collect(
Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Person::getName))), ArrayList::new)
);
unique.forEach(p -> System.out.println(p));
3、第二种java8写法
List<String> names = new ArrayList<>();//用来临时存储person的id
List<Person> personList = persons.stream().filter(// 过滤去重
v -> {
boolean flag = !names.contains(v.getName());
names.add(v.getName());
return flag;
}
).collect(Collectors.toList());
二、保证添加顺序
1、方式一 利用HashSet不能添加重复数据的特性 由于HashSet不能保证添加顺序,所以只能作为判断条件:
private static void removeDuplicate(List<String> list) {
HashSet<String> set = new HashSet<String>(list.size());
List<String> result = new ArrayList<String>(list.size());
for (String str : list) {
if (set.add(str)) {
result.add(str);
}
}
list.clear();
list.addAll(result);
}
2、方式二 利用LinkedHashSet不能添加重复数据并能保证添加顺序的特性 :
private static void removeDuplicate(List<String> list) {
LinkedHashSet<String> set = new LinkedHashSet<String>(list.size());
set.addAll(list);
list.clear();
list.addAll(set);
}
3、方式三 利用List的contains方法循环遍历:
private static void removeDuplicate(List<String> list) {
List<String> result = new ArrayList<String>(list.size());
for (String str : list) {
if (!result.contains(str)) {
result.add(str);
}
}
list.clear();
list.addAll(result);
}
一、去重
1、List、List对象去重复值
利用Set集合的特性:
Set<String> set = new LinkedHashSet<>();
set.addAll(list);
list.clear();
list.addAll(set);
通过JDK1.8新特性stream的distinct方法,可以直接处理:
List<String> list = list.stream().distinct().collect(Collectors.toList());
2、List<Student>中对象去重复值
这种的话,不能直接比较List中的对象,需要重写bean对象的equals和hashCode方法,然后通过进行去重,具体例子如下:
public class Student
private Long id;
private String name;
重写Student对象的equals()方法和hashCode()方法:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student Student = (Student) o;
if (!id.equals(Student.id)) return false;
return name.equals(Student.name);
}
@Override
public int hashCode() {
int result = id.hashCode();
result = 19 * result + name.hashCode();
return result;
}
List<Student> students = Arrays.asList(s1, s2, s3);
List<Student> studentsNew = new ArrayList<>();
// 去重
students.stream().forEach(
s -> {
if (!studentsNew.contains(s)) {
studentsNew.add(s);
}
}
);
List的contains()方法实际上是用对象的equals方法去比较
3、根据对象的属性去重
java8的stream流能完美解对象集合去重问题:
List<UserCar> list1 = new ArrayList();
UserCar userCar = new UserCar();
userCar.setId(1);
userCar.setCarNo("AA");
list1.add(userCar);
UserCar userCar1 = new UserCar();
userCar1.setId(2);
userCar1.setCarNo("AA");
list1.add(userCar1);
Person p1 = new Person(1, "11");
Person p2 = new Person(1, "22");
Person p3 = new Person(2, "11");
List<Person> persons = Arrays.asList(p1, p2, p3);
1、不使用java8
private List<UserCar> removeDupliByRecordId(List<UserCar> userCars) {
Set<UserCar> personSet = new TreeSet<UserCar>((o1, o2) -> o1.getRecordId().compareTo(o2.getRecordId()));
personSet.addAll(userCars);
return new ArrayList<UserCar>(personSet);
}
这也是大多数人第一想到的,借助 TreeSet 去重,其中 TreeSet 的其中一个构造函数接收一个排序的算法,同时这也会用到 TreeSet 的去重策略上。
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
2、第一种java8写法
List<Person> unique = persons.stream().collect(
Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Person::getName))), ArrayList::new)
);
unique.forEach(p -> System.out.println(p));
3、第二种java8写法
List<String> names = new ArrayList<>();//用来临时存储person的id
List<Person> personList = persons.stream().filter(// 过滤去重
v -> {
boolean flag = !names.contains(v.getName());
names.add(v.getName());
return flag;
}
).collect(Collectors.toList());
二、保证添加顺序
1、方式一 利用HashSet不能添加重复数据的特性 由于HashSet不能保证添加顺序,所以只能作为判断条件:
private static void removeDuplicate(List<String> list) {
HashSet<String> set = new HashSet<String>(list.size());
List<String> result = new ArrayList<String>(list.size());
for (String str : list) {
if (set.add(str)) {
result.add(str);
}
}
list.clear();
list.addAll(result);
}
2、方式二 利用LinkedHashSet不能添加重复数据并能保证添加顺序的特性 :
private static void removeDuplicate(List<String> list) {
LinkedHashSet<String> set = new LinkedHashSet<String>(list.size());
set.addAll(list);
list.clear();
list.addAll(set);
}
3、方式三 利用List的contains方法循环遍历:
private static void removeDuplicate(List<String> list) {
List<String> result = new ArrayList<String>(list.size());
for (String str : list) {
if (!result.contains(str)) {
result.add(str);
}
}
list.clear();
list.addAll(result);
}