龙空技术网

List集合你怎么去重?4年开发还在用双重循环,其实一行代码也行

石添的编程哲学 10828

前言:

当前你们对“去掉list中重复数据的快捷键”大致比较关注,大家都想要分析一些“去掉list中重复数据的快捷键”的相关资讯。那么小编在网络上网罗了一些关于“去掉list中重复数据的快捷键””的相关文章,希望你们能喜欢,姐妹们快快来学习一下吧!

[啤酒]满怀忧思,不如先干再说!做干净纯粹的技术分享!欢迎评论区或私信交流!

List集合特点是允许存在重复元素,在开发中从数据库获取批量数据时往往就是用List接收,去重就变成了一个重要的操作。

无论是老开发还是新手,对于去重的写法五花八门,身边的4年前端用JS去重时使用双重for循环,我当场直接笑趴,直呼高手,现已号称自己是实习生[狗头]!

去重是一个基本操作,并不会刻意思考,抱着能用就行的心态,往往写出不尽人意的代码,本章说一下List去重和多个List去除相同数据也就是【求差集】的实现方式!有复杂的也有一行代码搞定的,随君挑选

去重方式

单循环,新建集合去重,源集合不受影响双循环,在源集合基础上去重单循环坐标判断去重set去重stream去重stream求两个list差集返回正确推荐信息有如下集合

// 1、创建原始集合List<String> list = new ArrayList<>();list.add("山兔");list.add("阿米娅");list.add("小团团");list.add("原神派蒙");list.add("阿米娅");list.add("原神可莉");list.add("小团团");
循环去重

此方案是新建集合,循环原集合,如果当前元素不存在于新集合中,则添加元素到新集合中,最后的新集合就是需要的

// 2、创建新集合存储去重后数据List<Object> finallList = new ArrayList<>();// 3、循环遍历元素,如果不在新集合中就新增for (String item : list) {    // 判断    if(!finallList.contains(item)) {        finallList.add(item);    }}System.out.println("==================原集合==================");System.out.println(list);System.out.println("==================去重后集合==================");System.out.println(finallList);

输出结果

==================原集合==================[山兔, 阿米娅, 小团团, 原神派蒙, 阿米娅, 原神可莉, 小团团]==================去重后集合==================[山兔, 阿米娅, 小团团, 原神派蒙, 原神可莉]
双重循环去重

这种方式不需要创建新集合,使用双重循环判断删除重复元素

外循环从前往后遍历,逐个取出元素内循环从后往前遍历,循环到外循环当前元素处即可,之前的元素就不需要再做判断了【也可以从前往后遍历,只是已经比较过的区间还会再比较一次】

// 2、双重循环对比,删除已存在数据for (int i = 0; i < list.size() - 1; i++) {    // 内循环从后到外循环起始位置    for (int j = list.size() - 1; j > i; j--) {        // 内外循环当前元素相同就删除内循环的元素,因为它在后边,保障列表前半部分数据不重复        if(list.get(j).equals(list.get(i))) {            // 删除            list.remove(j);        }    }}System.out.println("==================去重后集合==================");System.out.println(list);
此时不能使用asList生成集合,因为asList生成的集合是不可变的,不能做删除元素和新增元素操作直接在源集合上做变更操作,如果不希望修改源集合则不推荐此用法for循环重复坐标去重

根据元素从前获取首次出现的坐标和从后获取首次出现的坐标,如果坐标值不同,则认为重复,移除后边的元素,保障集合前半部分数据不重复

// 2、复制一个集合List<String> copyList = new ArrayList<>(list);for (String item : list) {    // 判断首次出现的坐标和从后往前出现的坐标是否一致    if(copyList.indexOf(item) != copyList.lastIndexOf(item)) {        // 根据索引删除数据        copyList.remove(copyList.lastIndexOf(item));    }}System.out.println("==================去重后集合==================");System.out.println(copyList);

注意:一定要再复制一个集合,因为在使用for循环迭代集合时,不可以对集合做修改操作,否则会出现ConcurrentModificationException也就是并发修改异常,解决方案有几种,在接下来的文章中发出

Set 去重

Set集合自带去重,但是需要对象重写hashCodeequals方法判断是否为同一个对象,例子中使用的String类已经实现了hashCode和equals方法,下边会再使用自定义的对象

Set<String> set = new HashSet<>(list);List<String> finalList = new ArrayList<>(set);System.out.println("==================去重后集合==================");System.out.println(finalList);

使用Set就会变得无序,即元素的添加顺序和存储顺序不一致

==================原集合==================[山兔, 阿米娅, 小团团, 原神派蒙, 阿米娅, 原神可莉, 小团团]==================去重后集合==================[阿米娅, 原神派蒙, 山兔, 小团团, 原神可莉]

如果想保障有序,则可以使用LinkedHashSet

Set<String> set = new LinkedHashSet<>(list);List<String> finalList = new ArrayList<>(set);System.out.println("==================去重后集合==================");System.out.println(finalList);
自定义对象使用Set去重

自定义对象:重写hashCodeequals方法,当身份证号码一样时认为是同一个对象

import java.io.Serializable;import java.util.Objects;public class Driver implements Serializable {    private long id;    // 姓名    private String name;    // 身份证号码    private String idNumber;    public Driver(long id, String name, String idNumber) {        this.id = id;        this.name = name;        this.idNumber = idNumber;    }    // 省略getter、setter    @Override    public boolean equals(Object o) {        // 如果引用相等,则是同一个对象        if (this == o) return true;        // 如果为null,不是同一个类就直接返回false        if (o == null || getClass() != o.getClass()) return false;        Driver driver = (Driver) o;        // 根据身份证号码判断,如果相同就是同一个司机        return Objects.equals(idNumber, driver.idNumber);    }    /**     * 通过身份证号码计算哈希值     * @return     */    @Override    public int hashCode() {        return Objects.hash(idNumber);    }    // toString方法}

去除重复数据

// 1、创建原始集合List<Driver> list = new ArrayList<>();list.add(new Driver(1L,"山兔","411481XXX"));list.add(new Driver(2L,"阿米娅","412481XXX"));list.add(new Driver(3L,"小团团","413481XXX"));list.add(new Driver(4L,"原神派蒙","414481XXX"));list.add(new Driver(5L,"阿米娅","412481XXX"));list.add(new Driver(6L,"原神可莉","416481XXX"));list.add(new Driver(7L,"小团团","413481XXX"));System.out.println("==================原集合==================");System.out.println(list);Set<Driver> set = new HashSet<>(list);List<Driver> finalList = new ArrayList<>(set);System.out.println("==================去重后集合==================");System.out.println(finalList);
Stream去重

JDK8之后可以使用stream的distinct方法去重,非常清爽,前提是对象需要重写hashCode和equals方法,确定判重机制

List<Driver> list = new ArrayList<>();list.add(new Driver(1L,"山兔","411481XXX"));list.add(new Driver(2L,"阿米娅","412481XXX"));list.add(new Driver(3L,"小团团","413481XXX"));list.add(new Driver(4L,"原神派蒙","414481XXX"));list.add(new Driver(5L,"阿米娅","412481XXX"));list.add(new Driver(6L,"原神可莉","416481XXX"));list.add(new Driver(7L,"小团团","413481XXX"));// 去重List<String> finalList = list.stream().distinct().collect(Collectors.toList());
两个List获取差集

有以下场景,比如推荐的书单中有你不感兴趣的类型,则该类型的书就不会推荐给你,实现思路:

从数据库中查询到一堆数据【这里直接使用List初始化数据】从数据库查询到你不感兴趣的类型【这也是用List初始化】判断查出来的书的类型如果存在于不感兴趣列表则过滤掉书类

import java.io.Serializable;public class Book implements Serializable {    private long id;    private String name;    private String type;    public Book(long id, String name, String type) {        this.id = id;        this.name = name;        this.type = type;    }    public long getId() {        return id;    }    public void setId(long id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getType() {        return type;    }    public void setType(String type) {        this.type = type;    }    @Override    public String toString() {        return "Book{" +                "id=" + id +                ", name='" + name + '\'' +                ", type='" + type + '\'' +                '}';    }}
测试类
import java.util.*;import java.util.stream.Collectors;public class ArrayTest {    public static void main(String[] args) {        // 1、创建原始集合        List<Book> list = new ArrayList<>();        list.add(new Book(1L,"我与地坛","文学"));        list.add(new Book(2L,"生死疲劳","文学"));        list.add(new Book(3L,"一地鸡毛","文学"));        list.add(new Book(4L,"明朝那些事儿","历史"));        list.add(new Book(5L,"长安的荔枝","历史"));        list.add(new Book(6L,"高效能人士的七个习惯","成功学"));        list.add(new Book(7L,"励志生存","成功学"));        // 2、不感兴趣的类型        List<String> indiffTypeList = Arrays.asList("成功学","心理");        // 3、使用stream的filter过滤数据       //  通过contains方法判断该类型的书是否存在与不感兴趣列表中,【取反】即返回有用的数据        List<Book> resultList = list.stream().filter(item -> !indiffTypeList.contains(item.getType())).collect(Collectors.toList());        for (Book book : resultList) {            System.out.println(book);        }    }}

输出结果:已经排除掉不感兴趣的类型

Book{id=1, name='我与地坛', type='文学'}Book{id=2, name='生死疲劳', type='文学'}Book{id=3, name='一地鸡毛', type='文学'}Book{id=4, name='明朝那些事儿', type='历史'}Book{id=5, name='长安的荔枝', type='历史'}

这就是List去重的几种方案和项目开发时会用到的数据过滤,多多练习解锁更多玩法,赶紧使用起来吧,如有任何问题欢迎评论区交流

标签: #去掉list中重复数据的快捷键 #c语言双重循环 #list集合的size方法 #js双重for循环