黑马程序员——集合框架

来源:互联网 发布:linux write 编辑:程序博客网 时间:2024/05/20 13:14

------- android培训、java培训、期待与您交流! ----------

 

Set集合

Set特点:无顺序, 不可重复,便利方式只有用Iterator

 

HashSet

HashSet

1.      HashSet底层是由哈希表支持的,hashSet里面的元素都是唯一的,如果一个与已经存在集合的元素相等的元素师不会被添加到集合中的, 方法参照jdk-api

2.      保证元素唯一性

1)      如果两个对象的equals结果为true, hashCode值不相等,这两个元素不是相等的

2)      如果两个对象的eqauls结果为false, hashCode值相等,这两个元素不是相等的

3)      如果两个对象的equals结果为true, hashCode值相等,这两个元素师相等的

注意: 当元素插入Set中时如果hashCode与之前元素不相等,那么直接插入集合, 不会判断equals结果

3.      如何重写hashCode

重写hashCode的方式有多种,只要指定一个固定的值即可, 但是由于不同类型的对象可能会有相同的hashcode,所以建议用以下的方法减小重复的概率

quals方法中比较的属性的hashCode()加上另一个其它属性的hashCode乘上一个质数,如果属性类型是基本数据类型, 可以用包装类获取的hashCode进行计算

例如: int I = 31; return new Integer(id).hashCode() + name.hashCode() * I;

 

示例代码:

import java.util.*;class HashSetTest {public static void main(String[] args) {// 创建一个HashSeet对, <>里面的内容可以忽略HashSet<Student> set = new HashSet<Student>();// 向set添加两个内容不同的对象set.add(new Student("张三", 15));set.add(new Student("李四", 15));// 迭代输出System.out.println("将两个内容不同的对象添加到set: ");for (Iterator<Student> iter = set.iterator(); iter.hasNext();) {System.out.println(iter.next());}// 再添加一个内容为"张三", 15的Student对象set.add(new Student("张三", 15));// 迭代输出System.out.println("将与之前存在的对象内容一样的新对象添加到集合set: ");for (Iterator<Student> iter = set.iterator(); iter.hasNext();) {System.out.println(iter.next());}}}


 

//定义一个Student对象class Student {//Student有两个属性, 姓名和年龄String name;int age;//构造方法Student(String name, int age) {this.name = name;this.age = age;}//重写equals方法public boolean equals(Object obj) {//如果两个对象是同一个对象返回trueif (this == obj) {return true;}//如果两个对象时同一个字节码文件, 那么将obj强转为Studentif (this.getClass() == obj.getClass()) {Student s = (Student)obj;//根据姓名和年龄两个属性比较boolean b = this.name.equals(s.name) && this.age == s.age;return b;}return false;}//重写hashCode()public int hashCode() {return this.name.hashCode() + new Integer(this.age).hashCode() * 31;}//重写toString方法public String toString() {StringBuilder s = new StringBuilder();s.append("姓名: " + this.name);s.append("\t年龄: " + this.age);return s.toString();}}


 

LinkedHashSet

1.      LinkedHashSet继承自HashSet

2.      特点

取出元素的顺序与装入的顺序一致,可以理解为不重复, 有序

代码示例:

import java.util.*;class LinkedHashSetTest {public static void main(String[] args) {// 创建一个LinkedHashSet对象LinkedHashSet list = new LinkedHashSet();// 添加元素list.add("hello");list.add("world");list.add(123);list.add(true);// 迭代输出for (Iterator iter = list.iterator(); iter.hasNext();) {System.out.println(iter.next());}}}


 

TreeSet

1.      特点

集合中的元素有顺序, 不可重复, 这里的有顺序不是指添加与取出的顺序,而是它会有一个升序的自然顺序, 也可以自定义排列顺序

TreeSet底层是二叉树实现的,每次添加元素都要通过二叉树比较, 效率比HashSet

2.      保证元素唯一性

1)      实现Comparable接口重写compareTo方法

此方法返回一个int型的整数,可以将类内的一个属性进行比较, 如果小于0,那么对象在字典顺序前面, 如果大于0,在字典顺序后面, 等于0,两个对象相等

2)      实现Comparator自定义比较器

必须重写Comparator接口中的compare()方法,此方法实现的功能与上面的compateTo()一样

 

注意: 使用比较器在创建集合时,将其作为参数传递TreeSet(Comparator c), jdk1.5jdk1.6版本中第一次向TreeSet添加元素师不会进行比较,jdk1.7第一次添加元素也会执行比较

 

代码示例

import java.util.*;class TreeSetTest {public static void main(String[] args) {// 创建一个TreeSet对象TreeSet set1 = new TreeSet();// 创建三个学生对象Student s1 = new Student(2, "张三", 15);Student s2 = new Student(3, "李四", 14);Student s3 = new Student(1, "王五", 16);set1.add(s1);set1.add(s2);set1.add(s3);// id自然顺序System.out.println("按id的自然顺序排列");System.out.println("编号\t姓名\t年龄");for (Iterator iter = set1.iterator(); iter.hasNext();) {System.out.println(iter.next());}// 自定义比较器按年龄排序TreeSet set2 = new TreeSet(new MyComparator());// TreeSet set2 = new TreeSet();set2.add(s1);set2.add(s2);set2.add(s3);System.out.println("自定义比较器按年龄排列");System.out.println("编号\t姓名\t年龄");for (Iterator iter = set2.iterator(); iter.hasNext();) {System.out.println(iter.next());}}}// 定义一个Student类实现Comparable接口class Student implements Comparable {// 三个属性int id;String name;int age;// 构造Student(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}// 重写compareTo()public int compareTo(Object obj) {Student s = null;// 将obj转换为当前对象类型if (this.getClass() == obj.getClass()) {s = (Student) obj;}// 按照id比较if (this.id < s.id) {return -1;}if (this.id > s.id) {return 1;}return 0;}// toString()public String toString() {StringBuilder s = new StringBuilder();s.append(this.id);s.append("\t" + this.name);s.append("\t" + this.age);return s.toString();}}// 自定义比较器class MyComparator implements Comparator {// 重写compare方法public int compare(Object o1, Object o2) {Student s1 = (Student) o1;Student s2 = (Student) o2;// 按照age比较if (s1.age < s2.age) {return -1;}if (s1.age > s2.age) {return 1;}return 0;}}


 

Set总结

HashSet 底层哈希表实现,无序, 不重复, hashCodeequals确保唯一性,线程不安全

         |----- LinkedHashSet继承自HashSet, 装入取出顺序一致,线程不安全

TreeSet 底层是二叉树,有序, 不重复,线程不安全,TreeSet效率低,自然顺序, 比较器确保唯一,如果是compare结果为0,那么是重复的

 

Set遍历集合代码

HashSet为例

import java.util.*;class SetLoop {public static void main(String[] args) {System.out.println("Set..............");HashSet set = new HashSet();set.add("a");set.add("b");set.add("c");set.add("d");set.add("e");System.out.println("只有这一种方式: iterator");for (Iterator iter = set.iterator(); iter.hasNext();) {System.out.println(iter.next());}}}


 

原创粉丝点击