黑马程序员--Java基础学习笔记【集合-Set】

 

 ------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------    

 

Set 接口特点:

    不允许存储重复元素无序集合:存储取出没有顺序(不保证迭代顺序),没有索引

Set接口方法,和父接口Collection抽象方法完全一样

Set接口存储对象并迭代,找实现类HashSet集合

  • HashSet 如何保证元素唯一?

    Set里的元素是不能重复的,使用 equals() 方法和 hashCode() 方法来区分重复与否。覆盖 equals() 方法、hashCode() 方法用来判断两个对象是否为同一对象,而“==”判断地址是否相等,用来决定引用值是否指向同一对象。

    底层数据结构是哈希表,哈希表依赖于哈希值存储,添加功能底层依赖于两个方法 inthashCode(), boolean equals(Object obj) ,当存储对象时,先调用对象的 hashCode() 方法,校验哈希值是否与哈希表中已存在对象的哈希值相等,如果相等,当前对象调用 equals() 方法与表中已存在对象进行比较,如果结果是 true ,则哈希值一样,且比较结果为 true ,集合判断为同一对象不再存储。

   

    如果两个对象,哈希值一样,equals一定返回 true 吗?不一定

    如果两个对象,equals方法返回 true,拥有相同的哈希值吗?一定

 

HashSet特性:无序,不重复,无索引

    底层数据结构是哈希表:数组 + 链表实现(元素是链表的数组)

    存取速度都非常快,线程不安全集合,运行速度快

  • HashMap HashSet 有什么关系?

HashSet 底层是采用 HashMap 实现的。

privatetransient HashMap<E, object> map;

HashSet 类里面定义的一个私有成员变量。放进 HashSet 中的对象,其实是用这个HashMap key 来存储的。当调用 HashSet add 方法时,实际上是向 HashMap 中增加了一行 (key-value) 对,该行的 key 就是向 HashSet 增加的那个对象,该行的 value 就是一个 Object 类型的常量(静态的 Object 对象)。

 

LinkedHashSet特点:元素有序(由链表保证)唯一(由哈希表保证)

    since JDK1.4 ,出现时间晚于 Set 接口和父类 HashSet

    继承 HashSet

存储和取出的顺序是一致的

底层结构是基于哈希表的链表实现

    线程不安全集合

    Set 接口是无序的集合,而LinkedHashSet 变成有序集合。

 

TreeSet 集合的自身特性:

    底层数据结构是红黑树(自平衡的二叉树),保证元素的排序和唯一性

    线程不安全,运行速度快

    对存储的对象进行排序:

自然顺序排序

    java.lang.Comparable对实现类的对象进行强制排序)

自定义的对象的类 implementsComparable<>

重写接口中的 compareTo() 方法,建立自定义对象的自然顺序

根据创建集合时传递的比较器进行排序

    自定义比较器 implements Comparator<>

    重写接口中的 compare() 方法

 

    TreeSet存储自定义对象

       TreeSet集合存储对象时,不考虑hashCodeequals

      

  1. 1.  TreeSet集合依据对象的自然顺序进行排序

           要求存储到TreeSet集合中的对象,具有自然顺序

           类实现Comparable接口,重写compareTo

          

       2TreeSet集合自己具备比较性

           自定义比较器对象,实现java.util.Comparator,重写compare

           接口实现类对象,传递给TreeSet集合

           一旦有了比较器,TreeSet集合不考虑对象自然顺序

 

  • HashSet 集合存储自定义对象并遍历(如果对象的成员变量值相同即为同一个对象)

 

package cn.itcast.set;

 

importjava.util.HashSet;

import java.util.Set;

 

/*

 * HashSet存储自定义对象,不存储相同的元素

 * 校验对象的唯一性

 * 依赖于在自定义对象中重写hashCode equals 两个方法实现

 */

public classHashSetDemo {

 

    public static void main(String[] args) {

       Set<Person> set = new HashSet<>();

       set.add(new Person("zs", 20));

       set.add(new Person("ls", 21));

       set.add(new Person("zs", 20));

       for (Person person : set) {

           System.out.println(person);

       }

      

//     Person [name=ls, age=21]

//     Person [name=zs, age=20]

 

    }

 

}

 

  • TreeSet 集合存储自定义对象并遍历

(如果对象的成员变量值相同即为同一个对象,按照年龄进行从大到小进行排序)

 

package cn.itcast.set;

 

import java.util.TreeSet;

 

publicclassTreeSetDemo {

 

    publicstaticvoid main(String[] args) {

       TreeSet<String>set= newTreeSet<String>();

       set.add("www");

       set.add("itcast");

       set.add("cn");

       for (String string : set) {

           System.out.print(string + " ");

       }

       // cn itcast www 对存储的对象进行排序

       System.out.println();

      

       // 自然顺序比较

       TreeSet<Person>set2= newTreeSet<Person>();

       // 比较器比较

//     TreeSet<Person>set2 = new TreeSet<Person>(new PersonComparator());

       set2.add(new Person("zs", 20));

       set2.add(new Person("ls", 21));

      

       System.out.println(set2);

       // [Person [name=ls, age=21], Person [name=zs, age=20]]

    }

 

}

 

 

    /*

     * 重写接口compareTo方法,建立Person类自然顺序

     *

     * @seejava.lang.Comparable#compareTo(java.lang.Object)

     */

    @Override

    publicint compareTo(Person o) {

       intvalue = this.name.compareTo(o.name);

       if (value == 0) {

           returnthis.age - o.age;

       }

       returnvalue;

    }

 

package cn.itcast.set;

 

import java.util.Comparator;

 

publicclassPersonComparator implements Comparator<Person>{

 

    /*

     * (non-Javadoc)

     * @seejava.util.Comparator#compare(java.lang.Object, java.lang.Object)

     */

    @Override

    publicint compare(Person o1, Person o2) {

       intvalue = o1.getAge() - o2.getAge();

       if (value == 0) {

           returno1.getName().compareTo(o2.getName());

       }

       returnvalue;

    }

 

}

 

  • 键盘录入 5 个学生信息,按照总分从高到低输出到控制台

package cn.itcast.set;

 

importjava.util.Scanner;

import java.util.Set;

importjava.util.TreeSet;

 

public class SetTest1 {

    public static void main(String[] args) {

       Scanner sc = new Scanner(System.in);

       Set<StudentInfo> set = new TreeSet<StudentInfo>(new StudentScoreComparator());

       for (int i = 0; i < 3; i++) {

           String line = sc.nextLine();

           String[] str = line.split(" +");

           StudentInfo s = new StudentInfo(str[0],Integer.parseInt(str[1]), Integer.parseInt(str[2]),

                  Integer.parseInt(str[3]));

           set.add(s);

       }

       for (StudentInfo studentInfo : set) {

           System.out.println(studentInfo);

       }

    }

}

package cn.itcast.set;

 

import java.util.Comparator;

 

publicclassStudentScoreComparator implements Comparator<StudentInfo> {

 

    @Override

    publicint compare(StudentInfo o1, StudentInfo o2) {

       intvalue = o1.getTotal() - o2.getTotal();

       returnvalue == 0 ? o1.getName().compareTo(o2.getName()) : value;

    }

 

}


你可能感兴趣的:(集合框架,set)