您的位置:首页 > 职场人生

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

2015-04-29 01:48 423 查看
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

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<String> set = new HashSet<String>();
// 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<String> 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<Student> set = new HashSet<Student>();

// 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<String> set = new LinkedHashSet<String>();

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<Integer> set=new TreeSet<Integer>();
//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<Student> {

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<Student> ts = new TreeSet<Student>();

// 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<Student> ts = new TreeSet<Student>(); //无参数构造比较时就是使用元素的自然顺序
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
@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<Student> {

@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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: