1. Set 集合中元素不可重复,是无序的(存入和取出的顺序是不一样的),

    Set 接口中的方法和 Collection 接口一致.
  2. 常用子类:
    • HashSet : 内部数据结构是哈希表, 是不同步的

      • LinkedHashSet : 存入和取出的顺序一致(有序)
    • TreeSet : 可以对 Set 集合中的元素进行排序, 是不同步的.

HashSet

  1. 哈希表如何确定元素是否相同?

    1. 判断两个元素的哈希值是否相同,其实判断的是对象的 hashCode() 方法
    2. 如果哈希值相同,再判断两个对象的内容是否相同,用的是 equals() 方法
    3. 如果哈希值不同,是不需要判断 equals() 方法的
  2. HashSet 存储自定义对象
// 往 HashSet 集合中存储 Person 对象, 如果年龄和姓名相同,视为同一个人.
// 视为相同元素 // 自定义 Person 对象
public class Person{
private String name;
private int age; public Person(){
super();
} public Person(String name, int age){
super();
this.name = name;
this.age = age;
} public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
} // 覆盖 Object 类的 hashCode() 方法
public int hashCode(){ // 使用 String 类的 hashCode() 方法
return name.hashCode() + age;
} // 覆盖 Object 类的 equals() 方法
public boolean equals(Object obj){ if(this == obj)
return true;
if(!(obj instanceof Person))
throw new ClassCastException("类型错误"); Person p = (Person)obj; // 通过判断两者的姓名和年龄是否相同,确定返回值
return this.name.equals(p.name) && this.age == p.age;
}
} public class HashSetTest{
public static void main(String[] args){ HashSet hs = new HashSet(); /*
* HashSet 集合数据结构是哈希表,所以存储元素的时候,
* 首先使用元素的 hashCode() 方法来确定位置; 如果
* 位置相同, 在通过元素的 equals() 方法来确定元素是否
* 相同
*/
hs.add(new Person("lisi1",21));
hs.add(new Person("lisi2",22));
hs.add(new Person("lisi3",23));
hs.add(new Person("lisi4",24));
hs.add(new Person("lisi4",24)); Iterator it = hs.iterator();
while(it.hasNext()){
Person p = (Person)it.next();
System.out.println(p.getName()+"..."+p.getAge());
}
}
}
  1. 练习: 去除 ArrayList 集合中重复的元素
// ArrayList 集合存储的为字符串

public static void main(String[] args){

    ArrayList al = new ArrayList();

    al.add("abc1");
al.add("abc");
al.add("abc2");
al.add("abc1");
al.add("abc2"); System.out.println(al); al = getSingleElement(al); // 定义一个方法, 去除重复的元素
System.out.println(al);
} public static ArrayList getSingleElement(ArrayList al){ // 定义一个临时容器
ArrayList temp = new ArrayList(); // 迭代 al 集合
Iterator it = al.iterator();
while(it.hasNext()){
Object obj = it.next(); // 判断被迭代到的元素是否在临时容器中,
// 如果不在, 则存入临时容器
if(!temp.contains(obj)){
temp.add(obj);
}
} return temp;
} // ArrayList 集合存储自定义对象 public static void main(String[] args){ ArrayList al = new ArrayList(); al.add(new Person("lisi1",21));
al.add(new Person("lisi2",22));
al.add(new Person("lisi1",21));
al.add(new Person("lisi2",22));
al.add(new Person("lisi3",23));
al.add(new Person("lisi3",24)); System.out.println(al); al = getSingleElement(al); // 定义一个方法, 去除重复的元素
System.out.println(al);
} public static ArrayList getSingleElement(ArrayList al){ // 定义一个临时容器
ArrayList temp = new ArrayList(); // 迭代 al 集合
Iterator it = al.iterator();
while(it.hasNext()){
Object obj = it.next(); // 判断被迭代到的元素是否在临时容器中,
// 如果不在, 则存入临时容器
// Collection 接口中 contains() 方法,判断相同的依据是 equals() 方法 if(!temp.contains(obj)){
temp.add(obj);
}
} return temp;
}

LinkedHashSet

  • 特点: 元素不重复, 且有序(存入和取出的顺序一致)

TreeSet

  • 特点: 可以对 Set 集合中的元素进行指定顺序的排序,是不同步的.元素不可重复.
  • 保证元素唯一性的方式: 根据比较方法(compareTo()) 的返回结果. 如果是 0,就是相同元素.
// TreeSet 集合中存储 Perosn 对象
// TreeSet 集合对元素进行排序的方式一:
// 让元素自身具备比较功能, 元素需要实现 Comparable 接口,
// 覆盖 compareTo() 方法 // 自定义 Person 对象, 实现 Comparable 接口
public class Person implements Comparable {
private String name;
private int age; public Person(){
super();
} public Person(String name, int age){
super();
this.name = name;
this.age = age;
} public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
} // 覆盖 compareTo() 方法
// 以 Person 对象的年龄作为依据从小到大进行排序
// String 类具备 compareTo() 方法, 比较两个字符串的大小
public int compareTo(Object obj){ int temp = this.age - p.age;
return temp == 0 ? this.name.compareTo(p.name) : temp;
} } public class TreeSetTestDemo{
public static void main(String[] args){ TreeSet ts = new TreeSet(); ts.add(new Person("zhangsan",21));
ts.add(new Person("lisi",22));
ts.add(new Person("wangwu",24));
ts.add(new Person("zhaoliu",28)); while(ts.hasNext()){
Person p = (Perosn)it.next(); System.out.println(p.getName()+"..."+p.getAge());
}
}
} // TreeSet 集合第二种排序方式:(较常用)
// 应用场景: 不需要按照对象中具备的自然排序进行排序或者对象中不具备自然排序
// 让 TreeSet 集合具备比较功能.
// 定义一个类实现 Comparator 接口, 覆盖 compare 方法.
// 将该类对象作为参数传递给 TreeSet 集合的构造函数. // 创建一个根据 Person 类的 name 进行排序的比较器
public class ComparatorByName implements Comparator { public int compare(Object o1, Object o2){ Person p1 = (Person)o1;
Person p2 = (Person)o2; int temp = p1.getName().compareTo(p2.getName()); return temp == 0 ? p1.getAge()-p2.getAge() : temp;
}
} public class TreeSetTestDemo{
public static void main(String[] args){ // 将比较器作为参数传递给 TreeSet 集合的构造函数
TreeSet ts = new TreeSet(new ComparatorByName()); ts.add(new Person("zhangsan",21));
ts.add(new Person("lisi",22));
ts.add(new Person("wangwu",24));
ts.add(new Person("zhaoliu",28)); while(ts.hasNext()){
Person p = (Perosn)it.next(); System.out.println(p.getName()+"..."+p.getAge());
}
}
}

TreeSet 内部结构图解

_参考资料_
- [JavaSE 基础视频(毕向东)](https://www.bilibili.com/video/av3120015/#page=5)
- [JDK 1.6 中文文档](http://tool.oschina.net/apidocs/apidoc?api=jdk-zh)
- [Java提高篇——equals()与hashCode()方法详解](https://www.cnblogs.com/Qian123/p/5703507.html)

Set 接口常用子类及其特点的更多相关文章

  1. List 接口常用子类及其特点

    List 常用子类: - Vector: 内部是数组数据结构,是同步的. 增删, 查询都很慢 - ArrayList: 内部是数组数据结构,是不同步的,替代了 Vector,不同步的效率较高. 特点: ...

  2. 集合中Set接口与Collection接口,常用子类TreeSet,HashSet.

    Set接口与List接口的不同之处在于: 不允许有重复的数据. 定义如下: public interface Set<E>extends Collection<E> 主要方法与 ...

  3. Map集合,Map常用子类

    Map 集合 1,Collection中的集合,元素是孤立的,向季和忠储存的元素采用一个元素方式储存 2,Map中的集合,元素是成对存在的,每个元素中的集合称为双列集合 3,Collection中的集 ...

  4. Map集合概述和Map常用子类

    概述java.util.Map接口 Map<K,V> 有两个泛型 类型参数:K - 此映射所维护的键的类型V - 映射值的类型 特点:1.Map集合是双列集合,一个元素包含两个值,一个是k ...

  5. Map集合和Map常用子类

    Map集合 java.util.Map<K,V>集合 Map集合的特点: 1.Map集合是一个双列集合,一个元素包含两个值(Key,Value) 2.Map集合中的元素,key和value ...

  6. Spring Boot入门(四):开发Web Api接口常用注解总结

    本系列博客记录自己学习Spring Boot的历程,如帮助到你,不胜荣幸,如有错误,欢迎指正! 在程序员的日常工作中,Web开发应该是占比很重的一部分,至少我工作以来,开发的系统基本都是Web端访问的 ...

  7. Java开发知识之Java中的集合Set接口以及子类应用

    ---恢复内容开始--- Java开发知识之Java中的集合Set接口以及子类应用 一丶Set接口以及作用 在上一讲.我们熟悉了接口的实现图.以及自己各有的子类. List接口主要存储的数据是可以重复 ...

  8. 详解~实现Runnable方法创建线程之为什么要将Runnable接口的子类对象传递给Thread的构造函数

    /** * @author zhao * @TIME 0419 22:56 End *定义线程的第二种方法:实现Runnable接口(不考虑安全问题) *步骤:1,定义一个子类实现Runnable接口 ...

  9. python3 面向对象、类、继承、组合、派生、接口、子类重用父类方法

    对象是特征(变量)与技能(函数)的结合体而类是一系列对象共同的特征与技能的集合体 class teacher: lesson = "python" def __init__(sel ...

随机推荐

  1. 点滴积累【JS】---JS小功能(JS实现匀速运动)

    效果: 思路: 利用setInerval()计时器,进行运动.然后关键的一点是在最后停止的时候给它一个填充缝隙的判断. 代码: <head runat="server"> ...

  2. The Way to Go读书笔记_第4章_基本结构和基本数据类型

    “_”标识符 _ 本身就是一个特殊的标识符,被称为空白标识符.它可以像其他标识符那样用于变量的声明或赋值(任何类型都可以赋值给它),但任何赋给这个标识符的值都将被抛弃,因此这些值不能在后续的代码中使用 ...

  3. lseek,fcntl,ioctl函数

    函数说明:每一个已打开的文件都有一个读写位置, 当打开文件时通常其读写位置是指向文件开头, 若是以附加的方式打开文件(如O_APPEND), 则读写位置会指向文件尾. 当read()或write()时 ...

  4. 问题-Delphi7中JSON遍历节点不支持使用IN处理方法?

    相关资料:http://www.cnblogs.com/del/archive/2009/10/23/1588690.html 问题现象:在高版本中可以使用IN处理JSON的节点循环问题,可是发现D7 ...

  5. 使用uGUI系统玩转标准俄罗斯方块

    使用uGUI系统玩转标准俄罗斯方块 笔者使用的Unity3D版本是4.6b17.由于一些工作上的一些事情导致制作的进度被严重滞后.笔者实际用于开发俄罗斯方块的时间,大概也就2-3天吧. 开始前的准备 ...

  6. boa web服务器

      Boa是一种非常小巧的Web服务器,其可执行代码只有大约60KB左右.作为一种单任务Web服务器,Boa只能依次完成用户的请求,而不会fork出新的进程来处理并发连接请求.但Boa支持CGI,能够 ...

  7. php hash_hmac 与python hmac 区别

    使用 HMAC 方法生成带有密钥的哈希值 hash_hmac ( string $algo , string $data , string $key [, bool $raw_output = fal ...

  8. Java技术学习路线图

    一:常见模式与工具 学习Java技术体系,设计模式,流行的框架与组件是必不可少的: 常见的设计模式,编码必备 Spring5,做应用必不可少的最新框架 MyBatis,玩数据库必不可少的组件 二:工程 ...

  9. 第二百零六节,jQuery EasyUI,Menu(菜单)组件

    jQuery EasyUI,Menu(菜单)组件 学习要点: 1.加载方式 2.菜单项属性 3.菜单属性 4.菜单事件 5.菜单方法 本节课重点了解 EasyUI 中 Menu(菜单)组件的使用方法, ...

  10. Engineer in the White Spaces

     Engineer in the White Spaces Michael Nygard A SySTEM ConSiSTS oF inTERdEpEndEnT pRogRAMS. We call ...