Java学习笔记_22_Set接口的实现类

22.Set接口的实现类:

Set接口存放的元素是无序的且不包括反复元素。

1>实现类HashSet:

HashSet类依据元素的哈希码进行存放,取出时也能够依据哈希码高速找到。HashSet不保存元素的加入的顺序。

样例:

 import java.util.HashSet;
import java.util.Iterator;

public class Student {

public static void main(String[] args) {

HashSet<String> hs = new HashSet<String>();

hs.add("1 zxx");
hs.add("1 zxx");
hs.add("2 hahx");
hs.add("3 zyj");
hs.add("4 bmh");

Iterator<String> it = hs.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}

输出结果:

1 zxx

4 bmh

3 zyj

2 hahx

由于Set集合中不能存放反复的元素,所以对于自己定义的类,要重写hashCode()和equals()方法,用来推断元素是否为反复对象。

样例:

public class Student {

private int age;
private String name;

// get、set方法省略

public Student(int age, String name) {
this.age = age;
this.name = name;
}

// 重写HashCode方法
public int hashCode() {
return age * name.hashCode();
}

// 重写equals方法
public boolean equals(Object obj) {
Student s = (Student) obj;
return age == s.age && name.equals(s.name);
}
}

注:假设两个对象同样,那么它们的hashCode值一定要同样;假设两个对象的hashCode值同样,他们并不一定同样。

2>实现类LinkedHashSet:

LinkHashSet类依据元素的哈希码进行存放,同一时候用链表记录元素的增加顺序。

简单的字符集合样例:

import java.util.Iterator;
import java.util.LinkedHashSet;

public class TestLinkedHashSet {
public static void main(String[] args) {
//创建一个LinkedHashSet集合对象
LinkedHashSet<String> lhs = new LinkedHashSet<String>();
//向集合对象中加入字符串
lhs.add("zxx");
lhs.add("abc");
lhs.add("hik");
lhs.add("hik");
lhs.add(null);
//生成一个迭代器
Iterator<String> it = lhs.iterator();
//输出字符串
while(it.hasNext()){
System.out.println(it.next());
}
}
}


输出为:

zxx

abc

hik

Null

自己定义对象的集合使用样例:

创建Student类:

public class Student {
//创建属性
private int age;
private String name;
//生成属性的get和set方法
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//包括參数的构造函数
public Student(int age, String name) {
this.age = age;
this.name = name;
}
//重写toString方法
public String toString() {
return "age :" + age + " name :" + name;
}

// 重写HashCode方法
public int hashCode() {
return age * name.hashCode();
}

// 重写equals方法
public boolean equals(Object obj) {
Student s = (Student) obj;
return age == s.age && name.equals(s.name);
}
}

測试LinkedHashSet的主函数:

import java.util.Iterator;
import java.util.LinkedHashSet;

public class TestLinkedHashSet {
public static void main(String[] args) {
//创建一个LinkedHashSet集合对象
LinkedHashSet<Student> lhs = new LinkedHashSet<Student>();
//生成一些Student对象
Student sd1 = new Student(18, "zxx");
Student sd2 = new Student(23, "abc");
Student sd3 = new Student(25, "hik");
Student sd4 = new Student(25, "hik");
//向集合对象中加入Student对象
lhs.add(sd4);
lhs.add(sd2);
lhs.add(sd3);
lhs.add(sd1);
lhs.add(null);
//生成一个迭代器
Iterator<Student> it = lhs.iterator();
//输出字符串
while (it.hasNext()) {
System.out.println(it.next());
}
}
}

输出:

age :25 name :hik

age :23 name :abc

age :18 name :zxx

null

注:通过链表来存储对象,一般插入和删除效率比較高,检索效率相对较低。

3>实现类TreeSet:

TreeSet的构造方法:

· TreeSet(): 构造一个空树集。

· TreeSet(Collection c): 构造一个树集,并加入集合c中的全部元素。

· TreeSet(Comparator c): 构造一个树集,而且使用特定的比較器对其经行排序。

· TreeSet(SortedSet s): 构造一个树集,加入有序集合s中的全部元素,而且使用与有序集s同样的比較器排序。

注意:放入TreeSet中的元素必须是能够排序的。假若要对增加的Student类经行排序,

则要实现compareTo()方法,那么就必须实现Comparable接口。

排序Student集合类样例:

Student中的代码:

public class Student implements Comparable {
// 创建属性
private Integer age;
private String name;

// 包括參数的构造函数
public Student(Integer age, String name) {
this.age = age;
this.name = name;
}

// 生成属性的get和set方法
public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

// 重写toString方法
public String toString() {
return "age :" + age + " name :" + name;
}

// 重写HashCode方法
public int hashCode() {
return age * name.hashCode();
}

// 重写equals方法
public boolean equals(Object obj) {
Student s = (Student) obj;
return age == s.age && name.equals(s.name);
}

//重写compareTo(Object o)方法
public int compareTo(Object o) {
Student s = (Student) o;
if (s.getAge().compareTo(this.getAge()) > 0)
return -1;
else if (s.getAge().compareTo(this.age) == 0)
return 0;
else
return 1;
}
}

 

TestTreeSet类中的代码:

import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class TestTreeSet {
public static void main(String[] args) {
// 创建一个LinkedHashSet集合对象
Set<Student> ts = new TreeSet<Student>();
// 生成一些Student对象
Student sd1 = new Student(18, "zxx");
Student sd2 = new Student(23, "abc");
Student sd3 = new Student(25, "hik");
Student sd4 = new Student(25, "hik");
Student sd5 = new Student(17, "cde");
// 向集合对象中加入Student对象
lhs.add(sd4);
ts.add(sd2);
ts.add(sd5);
ts.add(sd3);
ts.add(sd1);
// 生成一个迭代器
Iterator<Student> it = ts.iterator();
// 输出字符串
while (it.hasNext()) {
System.out.println(it.next());
}
}
}

输出结果:

age :17 name :cde

age :18 name :zxx

age :23 name :abc

age :25 name :hik

非常明显TreeSet中的Student类按age由小到大的顺序排序。

使用Comparable接口能够完毕TreeSet的排序,但使用Comparable接口定义排序具有局限性,

实现此接口的类仅仅能按CompareTo()定义的这一种方法排序。假设同一类对象要有多种排序方式,

应该为该类定义不同的比較器。定义比較器实际上就是让自编写的类实现Comparator接口,

重写Comparator接口中的比較方法compare(Object a,Object b)。

排序Student集合类样例:

Student中的代码:

public class Student {
// 创建属性
private Integer age;
private String name;
private Integer score;

// 包括參数的构造函数
public Student(Integer age, String name, Integer score) {
this.age = age;
this.name = name;
this.score = score;
}

// 重写toString方法
public String toString() {
return "name :" + name + " age :" + age + " score :" + score;
}

// 生成属性的get和set方法
public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getScore() {
return score;
}

public void setScore(Integer score) {
this.score = score;
}

// 重写HashCode方法
public int hashCode() {
return age * score * name.hashCode();
}

// 重写equals方法
public boolean equals(Object obj) {
Student s = (Student) obj;
return age == s.age && name.equals(s.name)
&& score == s.score;
}
}

TestTreeSet类中的代码:

import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

//学生年龄比較器
class StudentAgeComparator implements Comparator<Student> {
public int compare(Student o1, Student o2) {
int i = o1.getAge() - o2.getAge();
return i;
}
}

// 学生成绩比較器
class StudentScoreComparator implements Comparator<Student> {
public int compare(Student o1, Student o2) {
int i = o1.getScore() - o2.getScore();
return i;
}
}

public class TestTreeSet {
public static void main(String[] args) {
// 创建一个LinkedHashSet集合对象
//按年龄有小到大排顺序
Set<Student> ts = new TreeSet<Student>(new
StudentAgeComparator());
//按成绩由小到大排序
//Set<Student> ts = new TreeSet<Student>(new
StudentScoreComparator());

// 生成一些Student对象
Student sd1 = new Student(18, "zxx", 60);
Student sd2 = new Student(23, "abc", 85);
Student sd3 = new Student(25, "hik", 45);
Student sd4 = new Student(25, "hik", 90);
Student sd5 = new Student(17, "cde", 33);

// 向集合对象中加入Student对象
ts.add(sd1);
ts.add(sd2);
ts.add(sd3);
ts.add(sd4);
ts.add(sd5);

// 生成一个迭代器
Iterator<Student> it = ts.iterator();

// 输出字符串
while (it.hasNext()) {
System.out.println(it.next());
}
}
}

当选用Set<Student> ts = new TreeSet<Student>(new StudentAgeComparator());时。

输出结果:

name :cde age :17 score :33

name :zxx age :18 score :60

name :abc age :23 score :85

name :hik age :25 score :45

非常明显是按年龄由小到大排序的。

当选用Set<Student> ts = new TreeSet<Student>(new StudentScoreComparator());时。

输出结果:

name
:cde age :17 score :33
name :hik age :25 score :45
name :zxx age :18 score
:60
name :abc age :23 score :85
name :hik age :25 score :90

非常明显是按成绩由小到大排序的。

时间: 2024-10-17 07:21:25

Java学习笔记_22_Set接口的实现类的相关文章

Java学习笔记_23_List接口实现类

23.List接口实现类: List接口继承了Collection接口,它是一个允许存在重复项的有序集合. 1>实现类ArrayList: ArrayList类支持可随需要而增长的动态数组.数组列表以一个原大小被创建,当超过了它的大小, 类集自动增大,当对象被删除后,数组就可以缩小. 优点:ArrayList类对于使用索引取出元素用较高的效率,他可以用索引快速定位对象. 缺点:ArrayList类对于元素的删除或插入速度较慢. 构造方法: · ArrayList(): 构造一个初始容量为10的空

Java学习笔记之接口

一.接口的概念与定义 首先考虑一个简单的接口的定义: public interface Output { int MAX_LINE = 40; void out(); void getData(String msg); } 定义接口使用关键字interface 修饰符interface前面的public可以省略,如果省略,则采用默认访问控制,即只有在相同包结构的代码才可以访问此接口 接口不可以有构造方法(区别于类中的构造方法) 接口里面的所有成员,包括常量.方法等都是public访问权限,所以在

Java学习笔记_24_Map接口

24.Map接口: Map接口定义了存储"键(key)-值(value)映射对"的方法,Map中不能有重复的"键", Map实现类中储存的"键-值"映射对是通过键来唯一标识的,Map底层的"键"使用Set来存放的, 所以Map中的映射对的"键"对应的类必须重写hashCode()和equals()方法, 常用String作为Map的"键".  Map的添加.删除操作: · Object 

Java学习笔记_21_Collection接口

21.Collection接口: 1>容器类的添加.删除: · add(Object o) :将对象添加到集合. · Remove(Object o) :删除集合中与o相匹配的对象. 2>容器中类的查询: · Size(): 返回集合中元素的个数. · isEmpty(): 判断集合中是否包含元素. · contains(Object o): 判断集合中是否包含指定元素. · iterator(): 返回集合的一个迭代器,用来访问该集合的元素. · contains(Collection c)

Java学习笔记之接口和抽象类

接口(interface)1.interface创建一个接口,implements实现接口 interface jiekou{} class lie implements jiekou{}2.接口可以有属性,但必须赋值,不建议在接口定义属性(可用于定义常量)3.接口,可以定义与接口同名的方法4.接口的所有方法都没有方法体 interface jiekou{void a();} 5.接口定义的方法的权限修饰默认是public,实现接口的类重写其方法时,必须显示声明public修饰:6.实现接口的类

JAVA学习笔记(四十八)- 适配器类 Adapter

适配器类 Adapter,对接口中的抽象方法进行空实现 import java.awt.Button; import java.awt.Frame; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEve

Java学习笔记48(DBUtils工具类一)

上一篇的例子可以明显看出,在增删改查的时候,很多的代码都是重复的, 那么,是否可以将增删改查封装成一个类,方便使用者 package demo; /* * 实现JDBC的工具类 * 定义方法,直接返回数据库的连接对象 * */ import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Stat

Java学习笔记49(DBUtils工具类二)

上一篇文章是我们自己模拟的DBUtils工具类,其实有开发好的工具类 这里使用commons-dbutils-1.6.jar 事务的简单介绍: 在数据库中应用事务处理案例:转账案例 张三和李四都有有自己的存款 主键 帐户名 余额 1 张三 1000 2 李四 10 要从张三的账户余额中转账800到李四账户 SQL语句实现: update xx set 余额 = 余额-800 where 主键=1 update xx set 余额 = 余额+800 where 主键=2 虽然操作成功,但是会出现问

Java学习笔记—多线程(并发工具类,java.util.concurrent.atomic包)

在JDK的并发包里提供了几个非常有用的并发工具类.CountDownLatch.CyclicBarrier和Semaphore工具类提供了一种并发流程控制的手段,Exchanger工具类则提供了在线程间交换数据的一种手段.本章会配合一些应用场景来介绍如何使用这些工具类. CountDownLatch CountDownLatch允许一个或多个线程等待其他线程完成操作.假如有这样一个需求:我们需要解析一个Excel里多个sheet的数据,此时可以考虑使用多线程,每个线程解析一个sheet里的数据,