ArrayList去重

简介: ArrayList去重

                 一.为什么要去重?,去重原理

1.为什么要进行去重

在使用集合框架时,我们经常需要对一个集合中的元素进行去重操作。去重操作可以使集合中不同的元素呈现出来,去掉重复元素,从而降低程序开销和提高计算效率。在实际项目中,我们可能会遇到需要对一些大数据量的集合进行去重操作,如果不进行去重操作,可能会严重影响程序的性能和运行效率。

对于ArrayList集合来说,虽然其允许存储重复元素,但是在某些业务场景下,我们需要保证元素不重复。因此,当我们需要对ArrayList集合中的元素进行去重时,就需要进行底层的去重操作。

在底层去重操作中,我们可以使用集合框架提供的HashSet类对ArrayList中的元素进行去重。它的底层实现是基于哈希表的,当我们将ArrayList中的元素添加到HashSet中时,HashSet会自动去重元素,从而实现ArrayList集合的去重。使用HashSet对ArrayList进行底层去重操作不仅性能高效,而且代码简洁

在进行去重时我们还可以通过equals方法方法的返回值来进行操作,并且因此来去除集合中的重复元素,当然小编还是更推荐使用HashSet对ArrayList进行元素去重

除此之外,在集合中进行去重操作还可以帮助提高程序的质量和可维护性。当我们需要基于某个字段进行去重操作时,我们可以将该字段作为元素的属性,并在equals和hashCode方法中使用该属性进行比较,这样可以提高程序的可读性和可维护性。

2.去重原理

在ArrayList中,如果我们需要对元素进行去重,需要注意元素类型是否正确重写了hashCode和equals方法。根据集合框架中的规定,如果两个元素的equals方法返回true,则它们的hashCode值必须相等。因此,正确重写equals方法是确保元素能够正确去重的关键。

在Java中,equals方法是用来比较两个对象是否相等的方法。当我们需要比较自定义对象时,需要重写equals方法,以便让其能够正确地比较两个对象是否相等。通常我们只需要重写equals方法,而不需要重写hashCode方法,因为在使用集合框架时,hashCode方法一般会被自动调用。

在重写equals方法时,我们需要遵循以下几个原则:

1. 自反性:对于任何非空引用x,x.equals(x)应该返回true。

2. 对称性:对于任何非空引用x和y,如果x.equals(y)返回true,则y.equals(x)也应该返回true。

3. 传递性:对于任何非空引用x、y和z,如果x.equals(y)返回true,并且y.equals(z)返回true,则x.equals(z)也应该返回true。

4. 一致性:对于任何非空引用x和y,连续多次调用x.equals(y)应该返回相同的结果。

5. 非空性:对于任何非空引用x,x.equals(null)应该返回false。

对于ArrayList来说,在去重时会先调用元素的equals方法判断两个元素是否相等,如果equals方法返回true,则判断这两个元素是重复的,只保留其中的一个副本。如果equals方法返回false,则认为这两个元素是不同的,不会进行去重操作。

需要注意的是,当我们使用ArrayList进行去重时,元素的equals方法的实现方式对去重结果有很大的影响。因此,在实现自定义对象的equals方法时,我们需要基于具体的业务场景来实现,以确保元素能够正确地去重。

                                二.实例

1.字符串去重

1.1代码截屏:

1.2代码效果图

1.3源码:

package com.lz.list;
import java.util.ArrayList;
import java.util.List;
public class demo4 {
  public static void main(String[] args) {
    /**
     * 字符串去重
     */
     List list = new ArrayList<>();
        list.add("q");
        list.add("f");
        list.add("h");
        System.out.println("当前原素:" + list);
        if (!list.contains("h")) {
            list.add("h");
        }
        System.out.println("现在原素:" + list);
}
}

2.对象去重

2.1代码截屏:

 

2.2代码效果图:

2.3源码:

package com.lz.list;
import java.util.ArrayList;
import java.util.List;
public class demo7 {
  public static void main(String[] args) {  
  /**
   * 对象去重
   */
    List list = new ArrayList<>();
    list.add(new  stu("多久哦"));
    list.add(new  stu("山东积分"));
    list.add(new  stu("速度放缓"));
    System.out.println("当前原素:" + list);
    if (!list.contains(new  stu("多久哦"))) {
      list.add(new  stu("多久哦"));
    }
    System.out.println("现在原素:" + list); 
  }
}
//创建一个对象
class  stu{ 
  private   String  name;
public stu() {
  // TODO Auto-generated constructor stub
}
  /* (non-Javadoc)
 * @see java.lang.Object#toString()
 */
//调用get set方法
@Override
public String toString() {
  return "stu [name=" + name + "]";
}
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public stu(String name) {
    super();
    this.name = name;
  }
  //创建    equals方法
  @Override
  public boolean equals(Object obj) {
    //为什么 会这样原因是    equals方法返回值相关
    System.out.println("送积分");
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    stu other = (stu) obj;
    if (name == null) {
      if (other.name != null)
        return false;
    } else if (!name.equals(other.name))
      return false;
    return true;
  }
}
相关文章
|
测试技术
华为测试工程师面试必备的问题点
华为测试工程师面试必备的问题点
336 0
|
消息中间件 存储 缓存
Java请求合并与分而治之
Java请求合并与分而治之
988 0
Java请求合并与分而治之
|
8月前
|
存储 缓存 人工智能
工作中,Redis的15种使用场景
Redis 在现代应用中扮演着至关重要的角色,涵盖缓存加速、分布式锁、实时排行榜、计数器、消息队列等15种常见场景。它通过高效的数据结构和原子操作,大幅提升系统性能和响应速度,广泛应用于会话管理、签到系统、限流控制、购物车、抽奖活动、全页缓存、发布订阅、地理位置服务、分布式ID生成及数据过期处理等领域。灵活运用这些特性,可显著优化开发效率和用户体验。
1177 0
工作中,Redis的15种使用场景
|
XML 安全 Java
掌握SpringBoot单点登录精髓,一键通行多系统,轻松打造无缝用户体验新纪元!
【8月更文挑战第29天】单点登录(SSO)是一种身份认证机制,用户在多个相互信任的应用系统中只需登录一次即可访问所有系统,无需重复输入凭证。本文详细介绍如何利用Spring Security和OAuth2在SpringBoot中实现SSO,并提供示例代码。核心步骤包括:引入依赖、配置认证服务器与资源服务器、实现单点登录拦截器及完成SSO配置。通过合理配置,SSO能显著提升用户体验和系统安全性。
684 2
|
关系型数据库 MySQL Java
spi机制打破双亲委派机制
在JDBC4及以上版本,连接MySQL数据库不再需要显式加载驱动(`Class.forName`),而是利用SPI机制。系统通过扫描`META-INF/services/java.sql.Driver`文件找到`com.mysql.cj.jdbc.Driver`并使用`ServiceLoader`由AppClassLoader加载。`DriverManager`在启动时加载所有可用的`Driver`实现,实现解耦和动态发现。虽然看起来逆向了双亲委派,但实际上每个类仍由适当的类加载器加载,保持了加载层次。
spi机制打破双亲委派机制
|
前端开发 JavaScript 微服务
微前端架构模式
微前端架构模式
|
安全 Java 数据库
第3章 Spring Security 的用户认证机制(2024 最新版)(上)
第3章 Spring Security 的用户认证机制(2024 最新版)
688 0
List.stream() .distinct() 去重 List,字母大写方法
List.stream() .distinct() 去重 List,字母大写方法
225 0
|
NoSQL Linux Redis
虚拟机VMWare+Linux系统CentOS7安装【Linux】
虚拟机VMWare+Linux系统CentOS7安装【Linux】
564 2
|
JavaScript Linux Shell
Linux系统计划任务之系统重启定时任务
Linux系统计划任务之系统重启定时任务
548 1