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 方法。

  • 相关阅读:
    Visifire正式版(v1.1)发布
    [转]PSP机能强大!已能模拟运行WINDOWS系统?
    在Silverlight+WCF中应用以角色为基础的安全模式(一)基础篇之角色为基础的安全模式简介 Virus
    C#的加密解密算法,包括Silverlight的MD5算法 Virus
    MMORPG programming in Silverlight Tutorial (10)Implement the sprite’s 2D animation (Part IV)
    Game Script: Rescue Bill Gates
    MMORPG programming in Silverlight Tutorial (9)KeyFrame Animation
    MMORPG programming in Silverlight Tutorial (5)Implement the sprite’s 2D animation (Part II)
    MMORPG programming in Silverlight Tutorial (7)Perfect animation
    MMORPG programming in Silverlight Tutorial (3)Animate the object (Part III)
  • 原文地址:https://www.cnblogs.com/Sherlock-J/p/12925984.html
Copyright © 2011-2022 走看看