如何判断集合中是否存在某个元素

在java中我们可以通过contains方法判断集合中是否已经有某个值;

1.List的contains(obj)方法

实际上,List调用contains(Object obj)方法时,会遍历List中的每一个元素,然后再调用每个元素的equals()方法去跟contains()方法中的参数进行比较,如果有一个元素的equals()方法返回true则contains()方法返回true,否则所有equals()方法都不返回true,则contains()方法则返回false。

2.Set的Contains(obj)方法

当调用HashSet的contains(Object obj)方法时,其实是先调用每个元素的hashCode()方法来返回哈希码,如果哈希码的值相等的情况下再调用equals(obj)方法去判断是否相等,只有在这两个方法所返回的值都相等的情况下,才判定这个HashSet包含某个元素。因此,需重写Course类的hashCode()方法和equals()方法。

3. Map中是否包含指定的Key和Value

在Map中,用containsKey()方法,判断是否包含某个Key值;用containsValue()方法,判断是否包含某个Value值。

注:跟List中的Contains()方法一样,Map中的ContainsValue()方法也需要调用某个Value值的equals()方法,去和参数对象进行比较,如果匹配成功,返回结果为true,说明在Map中的Value值确实包含参数对象。因此,需要重写Student类的equals()方法。

测试

  • String和自定义object类之间储存方式的区别
  • String和object在使用contains时的差别
  • List  Set  Map的不同表现
//注释为false的是错误,没写的是true

import java.util.*;

import javax.print.attribute.HashAttributeSet;

public class contains{
    public static void main(String[] args){

        String str1 = "aaa";
        String str11 = "aaa";
        String str2 = "bbb";

        //string 存储方式,重复字符串不会另行开辟空间
        System.out.println("String storage test:");
        System.out.println(str1 == "aaa");
        System.out.println(str1 == str11);
        System.out.println(str1.equals(str2));// false
        System.out.println(str1.equals("aaa"));

        Person p1 = new Person("A", 1);
        Person p11 = new Person("A", 1);
        Person p2 = new Person("B", 2);

        //new几个就有几个空间
        System.out.println("\nObject storage test");
        System.out.println(p1 == p11); // false
        System.out.println(p1.equals(p11));// false

        //list string
        List<String> list1 = new ArrayList<>();
        list1.add(str1);
        System.out.println("\nList String test:");
        System.out.println(list1.contains(str1));
        System.out.println(list1.contains("aaa"));
        System.out.println(list1.contains(str11));

        //list object
        List<Person> list2 = new ArrayList<>();
        list2.add(p1);
        System.out.println("\nList object test:");
        System.out.println(list2.contains(p1));
        System.out.println(list2.contains(p11));// false
        System.out.println(list2.contains(p2));// false

        //set string
        Set<String> set1 = new HashSet<String>();
        set1.add(str1);
        System.out.println("\nSet String test:");
        System.out.println(set1.contains(str1));
        System.out.println(set1.contains("aaa"));
        System.out.println(set1.contains(str11));

        //set object
        Set<Person> set2 = new HashSet<Person>();
        set2.add(p1);
        System.out.println("\nSet Object test:");
        System.out.println(set2.contains(p1));
        System.out.println(set2.contains(p11));// false
        System.out.println(set2.contains(p2));// false

        //map string
        Map<String,String> map1 = new HashMap<String, String>();
        map1.put(str1, str1);
        System.out.println("\nMap String test:");
        System.out.println(map1.containsKey(str1));
        System.out.println(map1.containsKey(str11));
        System.out.println(map1.containsValue(str1));
        System.out.println(map1.containsValue(str11));

        //map object
        Map<Person,Person> map2 = new HashMap<Person,Person>();
        map2.put(p1,p1);
        System.out.println("\nMap Object test:");
        System.out.println(map2.containsKey(p1));
        System.out.println(map2.containsKey(p11));// false
        System.out.println(map2.containsValue(p1));
        System.out.println(map2.containsValue(p11));// false
    }
}

class Person{
    private String name;
    private int age;

    public Person(String name,int age){
        this.name = name;
        this.age = age;
    }

    public String getName(){
        return this.name;
    }

    public int getAge(){
        return this.age;
    }
}

结果:String只要内容相同就被判断为true

 

重写Person的equal方法之后的结果:

//注释为false的是错误,没写的是true

import java.util.*;

import javax.print.attribute.HashAttributeSet;

public class contains{
    public static void main(String[] args){

        String str1 = "aaa";
        String str11 = "aaa";
        String str2 = "bbb";

        //string 存储方式,重复字符串不会另行开辟空间
        System.out.println("String storage test:");
        System.out.println(str1 == "aaa");
        System.out.println(str1 == str11);
        System.out.println(str1.equals(str2));// false
        System.out.println(str1.equals("aaa"));

        Person p1 = new Person("A", 1);
        Person p11 = new Person("A", 1);
        Person p2 = new Person("B", 2);

        //new几个就有几个空间
        System.out.println("\nObject storage test");
        System.out.println(p1 == p11); // false
        System.out.println(p1.equals(p11));

        //list string
        List<String> list1 = new ArrayList<>();
        list1.add(str1);
        System.out.println("\nList String test:");
        System.out.println(list1.contains(str1));
        System.out.println(list1.contains("aaa"));
        System.out.println(list1.contains(str11));

        //list object
        List<Person> list2 = new ArrayList<>();
        list2.add(p1);
        System.out.println("\nList object test:");
        System.out.println(list2.contains(p1));
        System.out.println(list2.contains(p11));
        System.out.println(list2.contains(p2));// false

        //set string
        Set<String> set1 = new HashSet<String>();
        set1.add(str1);
        System.out.println("\nSet String test:");
        System.out.println(set1.contains(str1));
        System.out.println(set1.contains("aaa"));
        System.out.println(set1.contains(str11));

        //set object
        Set<Person> set2 = new HashSet<Person>();
        set2.add(p1);
        System.out.println("\nSet Object test:");
        System.out.println(set2.contains(p1));
        System.out.println(set2.contains(p11));// false
        System.out.println(set2.contains(p2));// false

        //map string
        Map<String,String> map1 = new HashMap<String, String>();
        map1.put(str1, str1);
        System.out.println("\nMap String test:");
        System.out.println(map1.containsKey(str1));
        System.out.println(map1.containsKey(str11));
        System.out.println(map1.containsValue(str1));
        System.out.println(map1.containsValue(str11));

        //map object
        Map<Person,Person> map2 = new HashMap<Person,Person>();
        map2.put(p1,p1);
        System.out.println("\nMap Object test:");
        System.out.println(map2.containsKey(p1));
        System.out.println(map2.containsKey(p11));// false
        System.out.println(map2.containsValue(p1));
        System.out.println(map2.containsValue(p11));
    }
}

class Person{
    private String name;
    private int age;

    public Person(String name,int age){
        this.name = name;
        this.age = age;
    }

    public String getName(){
        return this.name;
    }

    public int getAge(){
        return this.age;
    }
    @Override
    public boolean equals(Object obj) {
        if(obj instanceof Person){
            if (this.getName().equals(((Person)obj).getName())
            &&(this.getAge() == ((Person)obj).getAge())){
                return true;
            }
        }
        return false;
    }
}

结果:不出所料的是,不同的拥有相同内容的Person可以equal,list 的contains 能够识别内容相同的 Person,然而 set 却没有变化 ,map 的 containsValue 能够识别内容相同的 Person,而containsKey 却不能。
这是一个很有趣的结果
原因是,set 和 map 的 containskey 在使用equals的同时,也会使用 hashCode() 方法,因此,两个方法返回都相同时,两个对象才能被视为相等。

 

重写hashCode()方法:

//注释为false的是错误,没写的是true

import java.util.*;

import javax.print.attribute.HashAttributeSet;

public class contains{
    public static void main(String[] args){

        String str1 = "aaa";
        String str11 = "aaa";
        String str2 = "bbb";

        //string 存储方式,重复字符串不会另行开辟空间
        System.out.println("String storage test:");
        System.out.println(str1 == "aaa");
        System.out.println(str1 == str11);
        System.out.println(str1.equals(str2));// false
        System.out.println(str1.equals("aaa"));

        Person p1 = new Person("A", 1);
        Person p11 = new Person("A", 1);
        Person p2 = new Person("B", 2);

        //new几个就有几个空间
        System.out.println("\nObject storage test");
        System.out.println(p1 == p11); // false
        System.out.println(p1.equals(p11));

        //list string
        List<String> list1 = new ArrayList<>();
        list1.add(str1);
        System.out.println("\nList String test:");
        System.out.println(list1.contains(str1));
        System.out.println(list1.contains("aaa"));
        System.out.println(list1.contains(str11));

        //list object
        List<Person> list2 = new ArrayList<>();
        list2.add(p1);
        System.out.println("\nList object test:");
        System.out.println(list2.contains(p1));
        System.out.println(list2.contains(p11));
        System.out.println(list2.contains(p2));// false

        //set string
        Set<String> set1 = new HashSet<String>();
        set1.add(str1);
        System.out.println("\nSet String test:");
        System.out.println(set1.contains(str1));
        System.out.println(set1.contains("aaa"));
        System.out.println(set1.contains(str11));

        //set object
        Set<Person> set2 = new HashSet<Person>();
        set2.add(p1);
        System.out.println("\nSet Object test:");
        System.out.println(set2.contains(p1));
        System.out.println(set2.contains(p11));
        System.out.println(set2.contains(p2));// false

        //map string
        Map<String,String> map1 = new HashMap<String, String>();
        map1.put(str1, str1);
        System.out.println("\nMap String test:");
        System.out.println(map1.containsKey(str1));
        System.out.println(map1.containsKey(str11));
        System.out.println(map1.containsValue(str1));
        System.out.println(map1.containsValue(str11));

        //map object
        Map<Person,Person> map2 = new HashMap<Person,Person>();
        map2.put(p1,p1);
        System.out.println("\nMap Object test:");
        System.out.println(map2.containsKey(p1));
        System.out.println(map2.containsKey(p11));
        System.out.println(map2.containsValue(p1));
        System.out.println(map2.containsValue(p11));
    }
}

class Person{
    private String name;
    private int age;

    public Person(String name,int age){
        this.name = name;
        this.age = age;
    }

    public String getName(){
        return this.name;
    }

    public int getAge(){
        return this.age;
    }
    @Override
    public boolean equals(Object obj) {
        if(obj instanceof Person){
            if (this.getName().equals(((Person)obj).getName())
            &&(this.getAge() == ((Person)obj).getAge())){
                return true;
            }
        }
        return false;
    }
    @Override
    public int hashCode() {
        return this.getAge();
    }
}

结论:set 的contains 和 map 的 containskey 在使用equals的同时,也会先使用 hashCode() 方法,在hashCode 相同的基础上再通过equals 判断是否相同。两个判断都相同时,才认定元素相等,contains 返回 true,之后的学习中也印证了,set 的 contains 使用hashcode 方法判断等价性是因为,上面例子中使用的是 hashset ,也就是,set 的下层实现方式是哈希,所以才会跟 hashcode 扯上关系。同理,map 也因为 hashmap 底层的哈希原理。


版权声明:本文为weixin_40159122原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。