zoukankan      html  css  js  c++  java
  • Java 之 removeAll

    在处理归并不同集合时去除其重复元素的时候没有什么好的方法,本来打算手撸一个去处重复元素的函数,但是想起集合类里肯定有解决这一问题的方法,就去查了一下 API ,还真有,那就是使用 removeAll() 。

    boolean removeAll(Collection<?> c)  
    从列表中移除指定 collection 中包含的其所有元素(可选操作)。

    直接用一个简单的例子来讲一下如何使用 removeAll() :

    public class Problems {
        private Integer id;
        private String title;
    
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        public String getTitle() {
            return title;
        }
        public void setTitle(String title) {
            this.title = title == null ? null : title.trim();
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof Problems )) {
                return false
            }
    
            Problems that = (Problems) o;
    
            if (getId() != null ? !getId().equals(that.getId()) : that.getId() != null){
                return false;
            }
            if (getTitle() != null ? !getTitle().equals(that.getTitle()) : that.getTitle() != null){
                return false;
            }
            return true;
        }
        @Override
        public int hashCode() {
            int result = getId() != null ? getId().hashCode() : 0;
            result = 31 * result + (getTitle() != null ? getTitle().hashCode() : 0);
            return result;
        }      
    }

    因为在执行removeAll方法时,会先对集合元素进行比较,如果元素相等才执行移除操作,说到这,相信很多人都已经明白是怎么回事了,因为不相等(equals),所以没有执行移除。也就是说直接使用 removeAll 是没有效果的,要在实体类中重写 hashCode 和 equals 方法才行。现在大多数 IDE 都支持自动生成实体类的 hashCode 和 equals 方法,不妨查一下你的 IDE 的快速生成方法,不然就得手撸了。
    然后现在就可以来试一下了:

    import java.util.ArrayList;  
    import java.util.List;  
    
    public class ProblemsList {  
    
        private List<Problems> subList;  
        private List<Problems> allList;  
    
        public UserList(){  
            subList=new ArrayList<Problems>();  
            allList=new ArrayList<Problems>();  
    
            for(int i=0;i<3;i++){  
                Problems problems=new Problems();  
                Problems.setId(i);  
                Problems.setTitle("This is"+i);  
                subList.add(Problems);  
            }  
    
           for(int i=0;i<10;i++){  
                Problems problems=new Problems();  
                Problems.setId(i);  
                Problems.setTitle("This is"+i);  
                subList.add(Problems);  
            }  
        }  
    
        public static void main(String[] args){  
            ProblemsList problemsList =new ProblemsList();  
            problemsList.allList.removeAll(problemsList.subList);//调用removeAll方法
            System.out.println(problemsList.allList.size());  
    
        }  
    }  

    OK了,到这里本来可以结束了,不过不妨再深入看看 removeAll:

        public boolean removeAll(Collection<?> c) {
            Objects.requireNonNull(c);
            boolean modified = false;
            Iterator<?> it = iterator();
            while (it.hasNext()) {
                if (c.contains(it.next())) {
                    it.remove();
                    modified = true;
                }
            }
            return modified;
        } 

    可以看到在调用removeAll方法时,其中调用了contains()方法,一块贴上源码:

        public boolean contains(Object o) {
            Iterator<E> it = iterator();
            if (o==null) {
                while (it.hasNext())
                    if (it.next()==null)
                        return true;
            } else {
                while (it.hasNext())
                    if (o.equals(it.next()))//这里调用了equals()方法
                        return true;
            }
            return false;
        } 

    但是很奇怪,为什么我们还要重写 hashCode 方法呢?来看官方文档:

    在 Java 应用程序执行期间,在同一对象上多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是对象上 equals 比较中所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
    如果根据 equals(Object) 方法,两个对象是相等的,那么在两个对象中的每个对象上调用 hashCode 方法都必须生成相同的整数结果。
    以下情况不 是必需的:如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么在两个对象中的任一对象上调用 hashCode 方法必定会生成不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同整数结果可以提高哈希表的性能。
    实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)
    当 equals 方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。

    抓下重点:
    1.如果根据 equals(Object) 方法,两个对象是相等的,那么在两个对象中的每个对象上调用 hashCode 方法都必须生成相同的整数结果。
    2.当 equals 方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
    也就是说,两个对象是相等的(equals ),那么其 hashCode 结果必须相等,所以有必要重写 hashCode 方法。

  • 相关阅读:
    yaml文件执行后常见错误解决
    动态存储管理实战:GlusterFS
    Kubernetes角色访问控制RBAC和权限规则(Role+ClusterRole)
    Kubernetes 存储系统 Storage 介绍:PV,PVC,SC
    在容器中管理数据的两种方式
    k8s 如何关联pvc到特定的pv
    Mysqldump 的 的 6 大使用场景的导出命令
    Docker 容器日志管理
    k8s中节点级别的日志
    k8s中pod的容器日志查看命令
  • 原文地址:https://www.cnblogs.com/Sherlock-J/p/12925984.html
Copyright © 2011-2022 走看看