Java高级之集合与泛型>Collection、Set、HashSet、LinkedHashSet、TreeSet

来源:互联网 发布:沪深300指数月度数据 编辑:程序博客网 时间:2024/06/06 01:30
一、Collection常用的方法:
Java 集合可分为 Set、List 和 Map 三种体系:Set:无序、不可重复的集合。List:有序,可重复的集合。Map:具有映射关系的集合。Collection 接口是 List、Set 和 Queue 接口的父接口,该接口里定义的方法既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合
import java.util.ArrayList;import java.util.Collection;import java.util.HashSet;import java.util.Iterator;public class TestCollections {    public static void main(String[] args) {        //1. 创建一个 Collection 接口的对象.         Collection collection = new ArrayList();        //2. Collection 重要方法说明:                 /**         * 2.1 用于添加元素的:         * add()         * addAll()         */        Person p1 = new Person();        collection.add(p1);        collection.add(new Person());        Collection collection2 = new ArrayList();        collection2.add(new Person());        collection2.add(new Person());        collection.addAll(collection2);        System.out.println(collection.size());         /**         * 2.2 用于访问集合的方法:          * 获取集合的长度: size()         * 对集合进行遍历的方法: iterator() 可以得到对应的 Iterator 接口对象.          *          * Iterator: 迭代器         * ①. 获取 Iterator 接口对象:          * ②. 使用 while 循环和 Iterator 对象遍历集合中的每一个元素. 具体使用 Iterator 接口的         *    hasNext() 和 next() 方法.          */        Iterator iterator = collection.iterator();        while(iterator.hasNext()){            Object obj = iterator.next();            System.out.println(obj);         }        /**         * 2.3 移除集合中的元素:          * remove(): 移除某一个指定的对象. 通过 equals() 方法来判断要移除的那个元素在集合中是否存在.                     以及是否能够成功移除.          * removeAll()         * clear(): 使集合中的元素置空.          *///        collection.clear();//        boolean result = collection.remove(p1);//        System.out.println(result); //        //        result = collection.removeAll(collection2);//        //        System.out.println(collection.size());         /**         * 2.4 用于检测集合的方法         * retains()         * retainsAll()         * isEmpty()         */        System.out.println(collection.contains(new Person()));//false        System.out.println(collection.contains(p1));//true        System.out.println(collection.containsAll(collection2));//true                System.out.println(collection.isEmpty()); //false//      collection.clear();        System.out.println(collection.isEmpty()); //true        /**         * 2.5 其他方法         * toArray():          * **T [] toArray(T[]): 涉及到泛型, 后面再说.          *          * equals(): 比较两个集合是否相等.          * hasCode():          */        Object [] objs = collection.toArray();        System.out.println(objs.length); //4                Person p2 = new Person();        Collection collection3 = new HashSet();//可换ArrayList()试试        collection3.add(p1);        collection3.add(p2);        Collection collection4 = new HashSet();        collection4.add(p2);        collection4.add(p1);        System.out.println(collection3.equals(collection4));         /**         * 使用增强 for 循环的方式来对集合进行遍历         */        for(Object obj: collection){            System.out.println(obj);         }    }}class Person(){}

 

二、Set、HashSet、LinkedHashSet

Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个 Set 集合中,则添加操作失败

Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals 方法

注意:

1、当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的

     hashCode 值, 然后根据 hashCode 值决定该对象在 HashSet 中的存储位置

2、如果两个元素的 equals() 方法返回 true,但它们的 hashCode() 返回值不相等,hashSet 将会

    把它们存储在不同的位置,但依然可以添加成功。

3、HashSet 集合判断两个元素相等的标准:两个对象通过 equals() 方法比较相等,并且两个对象的 

    hashCode() 方法返回值也相等。即:如果两个对象通过 equals() 方法返回 true,这两个对象的

    hashCode 值也应该相同

重写 hashCode() 方法的基本原则:

1、在程序运行时,同一个对象多次调用 hashCode() 方法应该返回相同的值。

2、当两个对象的 equals() 方法比较返回 true 时,这两个对象的 hashCode() 方法的返回值也应相等。

3、对象中用作 equals() 方法比较的 Field,都应该用来计算 hashCode 值。

另外:

1、LinkedHashSet 是 HashSet 的子类。

2、LinkedHashSet 集合根据元素的 hashCode 值来决定元素的存储位置,但它同时使用链表维护元素的次序,

     这使得元素看起来是以插入顺序保存的。

3、LinkedHashSet 性能插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能。

4、LinkedHashSet 有序但不允许集合元素重复

import java.util.HashSet;import java.util.Iterator;import java.util.LinkedHashSet;import java.util.Set;/** * 1. Set 是 Collection 的子接口 * 2. Set 中不允许存放相同的元素. 判定相同元素的标准是, 两个对象各调用 equals() 方法, 返回 true * 3. HashSet * 3.1 基本特征: * ①. 不能保证元素的排列顺序 * ②. HashSet 不是线程安全的 * ③. 集合元素可以使 null * ④. 对于 HashSet: 如果两个对象通过 equals() 方法返回 true,这两个对象的 hashCode 值也应该相同。 *  * 4. LinkedHashSet: * 4.1 LinkedHashSet 是 HashSet 的子类 * 4.2 使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的 * 4.3 LinkedHashSet 不允许集合元素重复 */public class TestSet {    public static void main(String[] args) {        Set set = new LinkedHashSet();                //new HashSet();                set.add(null);        System.out.println(set.size()); //1                Person p1 = new Person();        set.add(p1);        set.add(p1);        System.out.println(set.size()); //2                set.add(new Person("AA", 12));        set.add(new Person("AA", 12));        System.out.println(set.size()); //3                set.add(new Person("FF", 13));        Iterator it = set.iterator();        while(it.hasNext()){            System.out.println(it.next());         }    }} class Person {//    @Override//    public boolean equals(Object obj) {//        return false;//    }    private String name;    private int age;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public Person() {        // TODO Auto-generated constructor stub    }    public Person(String name, int age) {        super();        this.name = name;        this.age = age;    }//    private static int init = 0;        @Override    public int hashCode() {        final int prime = 31;        int result = 1;        result = prime * result + age;        result = prime * result + ((name == null) ? 0 : name.hashCode());        return result;//    return init++;    }    @Override    public boolean equals(Object obj) {        if (this == obj)            return true;        if (obj == null)            return false;        if (getClass() != obj.getClass())            return false;        Person other = (Person) obj;        if (age != other.age)            return false;        if (name == null) {            if (other.name != null)                return false;        } else if (!name.equals(other.name))            return false;        return true;    }    @Override    public String toString() {        return "Person [name=" + name + ", age=" + age + "]";    }    }


 

三、TreeSet:

TreeSet 是 SortedSet 接口的实现类,TreeSet 可以确保集合元素处于排序状态

TreeSet 支持两种排序方法:自然排序和定制排序默认情况下,TreeSet 采用自然排序

排序:

1、TreeSet 会调用集合元素的 compareTo(Object obj) 方法来比较元素之间的大小关系,

     然后将集合元素按升序排列。

2、如果试图把一个对象添加到 TreeSet 时,则该对象的类必须实现 Comparable 接口

3、实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过

    compareTo(Object obj)方法的返回值来比较大小

Comparable 的典型实现:

BigDecimal、BigInteger 以及所有的数值型对应的包装类:按它们对应的数值大小进行比较。

     Character:   按字符的 UNICODE 值来进行比较。

     Boolean:     true 对应的包装类实例大于 false 对应的包装类实例。

      String:       按字符串中字符的 UNICODE 值进行比较。

  Date、Time:   后边的时间、日期比前面的时间、日期大。

注意:

因为只有相同类的两个实例才会比较大小,所以向 TreeSet 中添加的应该是同一个类的对象

需要把一个对象放入 TreeSet 中,重写该对象对应的 equals() 方法时,应保证该方法与

compareTo(Object obj) 方法有一致的结果:即如果两个对象通过 equals() 方法比较返回 true,

则通过 compareTo(Object obj) 方法比较应返回 0.

import java.util.*;/*Set:无序,不可以重复元素。    |--HashSet:数据结构是哈希表。线程是非同步的。                保证元素唯一性的原理:判断元素的hashCode值是否相同。                如果相同,还会继续判断元素的equals方法,是否为true。    |--TreeSet:可以对Set集合中的元素进行排序。                底层数据结构是二叉树。                保证元素唯一性的依据:                compareTo方法return 0.                TreeSet排序的第一种方式:让元素自身具备比较性。                元素需要实现Comparable接口,覆盖compareTo方法。                也种方式也成为元素的自然顺序,或者叫做默认顺序。                TreeSet的第二种排序方式。                当元素自身不具备比较性时,或者具备的比较性不是所需要的。                这时就需要让集合自身具备比较性。                在集合初始化时,就有了比较方式。需求:往TreeSet集合中存储自定义对象学生。想按照学生的年龄进行排序。记住,排序时,当主要条件相同时,一定判断一下次要条件。*/class TreeSetDemo {    public static void main(String[] args)     {        TreeSet ts = new TreeSet();        ts.add(new Student("lisi02",22));        ts.add(new Student("lisi007",20));        ts.add(new Student("lisi09",19));        ts.add(new Student("lisi08",19));        //ts.add(new Student("lisi007",20));        //ts.add(new Student("lisi01",40));        Iterator it = ts.iterator();        while(it.hasNext())        {            Student stu = (Student)it.next();            System.out.println(stu.getName()+"..."+stu.getAge());        }    }}class Student implements Comparable//该接口强制让学生具备比较性。{    private String name;    private int age;    Student(String name,int age)    {        this.name = name;        this.age = age;    }    public int compareTo(Object obj)    {        //return 0;                if(!(obj instanceof Student))            throw new RuntimeException("不是学生对象");        Student s = (Student)obj;        System.out.println(this.name+"....compareto....."+s.name);        if(this.age>s.age)            return 1;        if(this.age==s.age)        {            return this.name.compareTo(s.name);        }        return -1;    }    public String getName()    {        return name;    }    public int getAge()    {        return age;    }}
import java.util.*;/*当元素自身不具备比较性,或者具备的比较性不是所需要的。这时需要让容器自身具备比较性。定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。当两种排序都存在时,以比较器为主。定义一个类,实现Comparator接口,覆盖compare方法。*/class Student implements Comparable//该接口强制让学生具备比较性。{    private String name;    private int age;    Student(String name,int age)    {        this.name = name;        this.age = age;    }    public int compareTo(Object obj)    {        //return 0;        if(!(obj instanceof Student))            throw new RuntimeException("不是学生对象");        Student s = (Student)obj;        //System.out.println(this.name+"....compareto....."+s.name);        if(this.age>s.age)            return 1;        if(this.age==s.age)        {            return this.name.compareTo(s.name);        }        return -1;    }    public String getName()    {        return name;    }    public int getAge()    {        return age;    }}class TreeSetDemo2 {    public static void main(String[] args)     {        TreeSet ts = new TreeSet();        ts.add(new Student("lisi02",22));        ts.add(new Student("lisi02",21));        ts.add(new Student("lisi007",20));        ts.add(new Student("lisi09",19));        ts.add(new Student("lisi06",18));        ts.add(new Student("lisi06",18));        ts.add(new Student("lisi007",29));        //ts.add(new Student("lisi007",20));        //ts.add(new Student("lisi01",40));        Iterator it = ts.iterator();        while(it.hasNext())        {            Student stu = (Student)it.next();            System.out.println(stu.getName()+"..."+stu.getAge());        }    }}class MyCompare implements Comparator{    public int compare(Object o1,Object o2)    {        Student s1 = (Student)o1;        Student s2 = (Student)o2;        int num = s1.getName().compareTo(s2.getName());        if(num==0)        {            return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));            /*            if(s1.getAge()>s2.getAge())                return 1;            if(s1.getAge()==s2.getAge())                return 0;            return -1;            */        }        return num;    }}


练习代码(定制排序)
比较推荐的定制排序做法
1、首先,定义一个Person类

public class Person {     private String name;     private int age;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public Person(String name, int age) {        super();        this.name = name;        this.age = age;    }    public Person(){}}


Person类

(附加的练习:Student类)

public class Student implements Comparable{    private String name;    private int age;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public Student(String name, int age) {        super();        this.name = name;        this.age = age;    }    @Override    public int hashCode() {        final int prime = 31;        int result = 1;        result = prime * result + age;        result = prime * result + ((name == null) ? 0 : name.hashCode());        return result;    }    @Override    public boolean equals(Object obj) {        if (this == obj)            return true;        if (obj == null)            return false;        if (getClass() != obj.getClass())            return false;        Student other = (Student) obj;        if (age != other.age)            return false;        if (name == null) {            if (other.name != null)                return false;        } else if (!name.equals(other.name))            return false;        return true;    }    @Override    public int compareTo(Object o) {        int result;        if(o instanceof Student){            Student stu = (Student)o;            result = this.age-stu.age;            if(result==0){            return this.getName().compareTo(stu.getName());            }        }else{            throw new ClassCastException("不是一个学生对象!");        }        return result;    }    public Student(){}    @Override    public String toString() {        return "Student [name=" + name + ", age=" + age + "]";    }        }


Student类

2、然后写主程序类

import java.util.Comparator;import java.util.Iterator;import java.util.Set;import java.util.TreeSet;public class TestTreeSet {      public static void main(String []args){/*          Set set = new TreeSet();//          set.add("123");//          set.add(123);//          set.add(null);//          set.add(new Student());          set.add(new Student("lisi07",22));          set.add(new Student("lisi02",16));          set.add(new Student("lisi008",22));          set.add(new Student("lisi10",19));          Iterator iterator = set.iterator();          while(iterator.hasNext()){              Student stu = (Student) iterator.next();              System.out.println(stu.getName()+"...."+stu.getAge());          }          for(Object obj:set){              System.out.println(obj);          }*/          Comparator comparator = new  Comparator() {            @Override            public int compare(Object o1, Object o2) {                int result;                  if(o1 instanceof Person&& o2 instanceof Person){                      Person p1 = (Person) o1;                      Person p2 = (Person) o2;                      result = p1.getAge() - p2.getAge();                    if(result == 0){                        return p1.getName().compareTo(p2.getName());                      }                  }else{                      throw new ClassCastException("不能转换为Person");                 }                     return result;            }        };        Set set2 = new TreeSet(comparator);        set2.add(new Person("lisi006",12));        set2.add(new Person("lisi002",6));        set2.add(new Person("lisi015",20));        set2.add(new Person("lisi013",20));        Iterator iterator = set2.iterator();        while(iterator.hasNext()){            Person p = (Person) iterator.next();            System.out.println(p.getName()+" "+p.getAge()+"\t");                 }        }}
0 0
原创粉丝点击