黑马程序员——Set集合概述及特点

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

Set集合概述及特点 

Set集合特点:无顺序不可重复

注意:我们学习set,它的方法没有特殊,也就是说,我们使用的是都是从 Collection中定义的方法.

我们学习Set集合,主要学习的是其数据结构(集合的特点)

 

Set接口下我们学习两个实现类

HashSet   TreeSet.

HashSet存储字符串并遍历

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);
		}
	}
}

HashSet存储自定义对象并遍历

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());

	}
}

HashSet保证元素唯一性的代码体现及图解

hashCode值的计算简单说,就是将对象中的属性的值相加

如果属性是基本数据类型,直接加

如果属性是引用类型,就得到其hash值在相加,

它们的结果乘以了一个质数,目的是为了减少重复率。

LinkedHashSet的概述和使用

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);
	}
}

TreeSet中重要概念

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);
		}
	}
}

TreeSet保证元素唯一以及排序的源码解析

基于 TreeMap 的 NavigableSet 实现。

使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator 进行排序,

具体取决于使用的构造方法。

 

1. new TreeSet();----à在TreeSet底层使用的是一个NavigableMap

2. 当调用put方法是,我们通过源代码连接时,是链接到Map接口,接口中没有具有的方法实现,这时我们就可以在Map接口中查找它的实现类   NavigableMap接口。

3. 在NavigableMap这个接口中也没有put方法实现,那么在看这个接口的实现类,

TreeMap中有put方法实现

TreeSet保证元素唯一性和自然排序的原理和图解

源代码分析 :

1. 当装入第一个元素时,因为集合中没有其它元素,那么它就是根

2. 所有元素在装入时,如果是小的一直放在左边,大的放在右边,相等的不装入。

问题:怎样比较的集合中的元素?

在源代码中有:

Comparator------比较器

Comparable----- 自然顺序 

什么是自然顺序?

实现了Comparable接口的类就具有了自然顺序,它比较时是通过接口中要重写的方法compareTo来完成的,这个方法返回的是int类型的值,0代表的是等于,负数代表的是小于,正数代表的是大于. 

比较器:在创建TreeSet时指定一个比较器

比较器就是实现了Comparator接口的一个类,那么这个类需要重写接口中一个方法compare,这个方法返回的是int类型值,它的原理与comparTo方法一样。


TreeSet存储自定义对象并遍历练习1(自然顺序)

学生类
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);
		}
	}
}

TreeSet存储自定义对象并遍历练习2(比较器)

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();
	}

}

关于Collection集合中选择问题

ArrayList

LinkedList

Vector

HashSet

TreeSet

1. 是否要保证集合中的元素重复

a) 不重复  HashSet  TreeSet

b) 可以重复ArrayList  LinkedList  Vector

2. 如果不重复的

HashSet

3. 如果可以重复

a) 查找  ArrayList

b) 删除,添加 LinkedList

但是,在开发,数据量如果不是特别大,就选择ArrayList.




你可能感兴趣的:(黑马程序员学习日记,黑马程序员,集合,set集合)