------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
Set集合特点:无顺序不可重复
注意:我们学习set,它的方法没有特殊,也就是说,我们使用的是都是从 Collection中定义的方法.
我们学习Set集合,主要学习的是其数据结构(集合的特点)
Set接口下我们学习两个实现类
HashSet TreeSet.
package cn.itcast.hashSet;
import java.util.HashSet;
import java.util.Iterator;
//向HashSet中存储字符串并遍历
//这个案例要求大家明白以下三点
//1.HashSet中的元素是不重复的
//2.HasSet中的元素是无顺序的----装入顺序与迭代出的顺序不一致,并且不保证元素的顺序永远不变
//3.HashSet集合怎样使用(遍历)---就是与Collection集合一样去使用
public class HashSetDemo1 {
public static void main(String[] args) {
// 1.创建一个HashSet集合.
HashSet set = new HashSet();
// 2.向集合中添加字符串元素
System.out.println(set.add("tom")); //true
System.out.println(set.add("james")); //true
System.out.println(set.add("fox")); //true
//System.out.println(set.add("james")); //false
set.add("a");
//3.遍历set集合 迭代器
// for(Iterator it=set.iterator();it.hasNext();){
// String s=it.next();
// System.out.println(s);
// }
//问题:增强for可不可以操作Set集合?
for(String s:set){
System.out.println(s);
}
}
}
package cn.itcast.hashSet;
import java.util.HashSet;
//创建一个HashSet,向其添加三个Student对象.
public class HashSetDemo3 {
public static void main(String[] args) {
// 1.创建一个HashSet集合
HashSet set = new HashSet();
// 2.创建三个学生对象.
Student s1 = new Student(1, "tom");
Student s2 = new Student(2, "fox");
Student s3 = new Student(1, "tom");
System.out.println(s1.equals(s3)); //没有重写equals方法时 s1==s3
//我们重写了equals,没有重写hashCode方法,这时s1.equals(s3)返回的是true
System.out.println("s1的hashCode:"+s1.hashCode());
System.out.println("s3的hashCode:"+s3.hashCode());
//我们将hashCode方法重写.
// 3.将三个学生对象添加到set集合中
set.add(s1);
set.add(s2);
set.add(s3);
System.out.println(set.size());
}
}
hashCode值的计算简单说,就是将对象中的属性的值相加
如果属性是基本数据类型,直接加
如果属性是引用类型,就得到其hash值在相加,
它们的结果乘以了一个质数,目的是为了减少重复率。
LinkedHashSet特点:可以保证元素的顺序(存入顺序与取出顺序一致)
package cn.itcast.hashSet;
import java.util.LinkedHashSet;
//LinkedHashSet它的用法与HashSet一样,只是它可以保证顺序。
public class LinkedHashSetDemo {
public static void main(String[] args) {
LinkedHashSet set = new LinkedHashSet();
set.add("a");
set.add("b");
set.add("k");
set.add("d");
System.out.println(set);
}
}
1. 知道TreeSet集合特点
不重复,可以对集合中元素进行排序。
2. 比较器
Comparator
3. 自然顺序
Comparable
4. TreeSet怎样保证集合中元素唯一 性
是通过自然顺序或比较器来判断的,compareTo compare方法如果返回的是0就代表重复了。
package cn.itcast.treeSet;
import java.util.TreeSet;
//向TreeSet集合中存储Integer数据并遍历
public class TreeSetDemo1 {
public static void main(String[] args) {
//1.创建TreeSet
TreeSet set=new TreeSet();
//2.向TreeSet中装入Integer数据
set.add(3);
set.add(1);
set.add(7);
set.add(2);
set.add(8);
//3.遍历TreeSet
for(int n:set){ //注意,类型应该是Integer,但是jdk1.5提供也自动拆箱,所以可以写int。
System.out.println(n);
}
}
}
基于 TreeMap 的 NavigableSet 实现。
使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator 进行排序,
具体取决于使用的构造方法。
1. new TreeSet();----à在TreeSet底层使用的是一个NavigableMap
2. 当调用put方法是,我们通过源代码连接时,是链接到Map接口,接口中没有具有的方法实现,这时我们就可以在Map接口中查找它的实现类 NavigableMap接口。
3. 在NavigableMap这个接口中也没有put方法实现,那么在看这个接口的实现类,
TreeMap中有put方法实现
源代码分析 :
1. 当装入第一个元素时,因为集合中没有其它元素,那么它就是根
2. 所有元素在装入时,如果是小的一直放在左边,大的放在右边,相等的不装入。
问题:怎样比较的集合中的元素?
在源代码中有:
Comparator------比较器
Comparable----- 自然顺序
什么是自然顺序?
实现了Comparable接口的类就具有了自然顺序,它比较时是通过接口中要重写的方法compareTo来完成的,这个方法返回的是int类型的值,0代表的是等于,负数代表的是小于,正数代表的是大于.
比较器:在创建TreeSet时指定一个比较器
比较器就是实现了Comparator接口的一个类,那么这个类需要重写接口中一个方法compare,这个方法返回的是int类型值,它的原理与comparTo方法一样。
package cn.itcast.treeSet;
//规定:Student的自然顺序就是年龄的顺序
public class Student implements Comparable {
private int id;
private String name;
private int age;
public Student(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Student o) {
// System.out.println(this);
// System.out.println(o);
// return this.age - o.age;
// 如果要根据name属性比较
return this.name.compareTo(o.name);
}
}
操作类
package cn.itcast.treeSet;
import java.util.TreeSet;
//存储自定义对象,并遍历
public class TreeSetDemo2 {
public static void main(String[] args) {
// 1.创建一个TreeSet集合
TreeSet ts = new TreeSet();
// 2.创建四个Student对象.
Student s1 = new Student(1, "tom", 20);
Student s4 = new Student(4, "lucy", 20);
Student s2 = new Student(2, "fox", 22);
Student s3 = new Student(1, "james", 21);
// 3.将四个学生添加到ts集合中
ts.add(s1);
ts.add(s4);
ts.add(s2);
ts.add(s3);
for(Student s:ts){
System.out.println(s);
}
}
}
package cn.itcast.treeSet;
import java.util.Comparator;
import java.util.TreeSet;
//存储自定义对象,并遍历 这时Student对象是具有自然顺序的,它的自然顺序是按照年龄排序。
//需求:将Student对象按照id排序输出.
//我们可以使用比较器,如果我们使用了比较器,虽然元素具有自然顺序,但是也按照 我们指定的比较器来排序,不按照自然顺序。
//问题:怎样创建比较器,怎样在TreeSet中使用比较器?
//1.要创建比较器,就可以创建一个类实现Comparator接口就可以,并重写其中的compare方法.
//2.在TreeSet中要使用比较器,需要使用new TreeSet(Comparator c);这个构造。
public class TreeSetDemo3 {
public static void main(String[] args) {
// 1.创建一个TreeSet集合
// TreeSet ts = new TreeSet(); //无参数构造比较时就是使用元素的自然顺序
TreeSet ts = new TreeSet(new Comparator() {
@Override
public int compare(Student o1, Student o2) {
return o1.getId() - o2.getId();
}
});
// 2.创建四个Student对象.
Student s1 = new Student(1, "tom", 20);
Student s4 = new Student(4, "lucy", 20);
Student s2 = new Student(2, "fox", 22);
Student s3 = new Student(3, "james", 21);
// 3.将四个学生添加到ts集合中
ts.add(s1);
ts.add(s4);
ts.add(s2);
ts.add(s3);
for (Student s : ts) {
System.out.println(s);
}
}
}
// 创建了一个比较器
class MyComparator implements Comparator {
@Override
public int compare(Student o1, Student o2) {
return o1.getId() - o2.getId();
}
}
ArrayList
LinkedList
Vector
HashSet
TreeSet
1. 是否要保证集合中的元素重复
a) 不重复 HashSet TreeSet
b) 可以重复ArrayList LinkedList Vector
2. 如果不重复的
HashSet
3. 如果可以重复
a) 查找 ArrayList
b) 删除,添加 LinkedList
但是,在开发,数据量如果不是特别大,就选择ArrayList.