集合框架 Set的特点:无序,不可以重复元素。

(1)HashSet:数据结构是哈希表。线程是非同步的。

              保证元素唯一性的原理:判断元素的hashCode值是否相同。

              如果相同,还会继续判断元素的equals方法,是否为true。





(2)TreeSet:可以对Set集合中的元素进行排序。

               底层数据结构是二叉树。

               保证元素唯一性的依据:compareTo方法return 0。



一、HashSet相关知识

    HashSet中的元素不可以重复,如果重复添加,则只会显示一个。

原理如下:

HashSet:底层数据结构是哈希表。是线程不安全的。不同步。

HashSet是如何保证元素唯一性的呢?

答:是通过元素的两个方法,hashCode和equals来完成。

如果元素的HashCode值相同,才会判断equals是否为true。如果元素的hashcode值不同,不会调用equals。



*******对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcode和equals方法**********



代码1:

package com.package2;

import java.util.*;

public class HashSet222
{ public static void main(String[] args)
{ HashSet hs = new HashSet(); hs.add("java01");
hs.add("java01");
hs.add("java02");
hs.add("java03");
hs.add("java03");
hs.add("java04"); Iterator it = hs.iterator(); while(it.hasNext())
{
System.out.println(it.next());
}
}
}

此demo将String类型的字符串添加进去,并且没有重复,结果如下:

java04

java02

java03

java01

由此我们可以断定,String类已经实现了hashcode()方法和equals()方法。打开,帮助文档,确实(这不是废话么^_^)

但是,如果我们要将自定义的元素add进HashSet中,则必须定义其自己的hashcode()方法和equals()方法。如下所示:

代码2:

package com.package2;
import java.util.*;
public class HashSet3
{
public static void main(String[] args)
{
HashSet hs = new HashSet(); hs.add(new Person("a1",11));
hs.add(new Person("a2",12));
hs.add(new Person("a3",13));
hs.add(new Person("a2",12));
hs.add(new Person("a4",14)); Iterator it = hs.iterator(); while(it.hasNext())
{
Person p = (Person)it.next();
System.out.println(p.getName()+"::"+p.getAge());
}
}
}
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.name = name;
this.age = age;
} public int hashCode()
{
System.out.println(this.name+"....hashCode");
return name.hashCode()+age*37; //保证此元素的返回值尽量不一致。
} public boolean equals(Object obj)
{ if(!(obj instanceof Person))
return false; Person p = (Person)obj;
System.out.println(this.name+"...equals.."+p.name); return this.name.equals(p.name) && this.age == p.age;
} public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}

输出结果如下:

a1....hashCode

a2....hashCode

a3....hashCode

a2....hashCode

a2...equals..a2

a4....hashCode

a1::11

a3::13

a2::12

a4::14

由此可以看出,将元素add时,会首先调用元素的hashcode()方法,当返回值重复时,会调用其equals方法。缺少任何一种方法都构不成一个HashSet集合。





二、TreeSet相关知识

TreeSet有俩种排序方式。

TreeSet排序的第一种方式:让元素自身具备比较性。

步骤:将add进TreeSet中的元素实现Comparable接口,并且覆盖compareTo方法。这种顺序也是元素的自然顺序,或者叫做默认顺序。



TreeSet的第二种排序方式。当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性(即利用其另一种构造函数建立对象)。在集合初始化时,就有了比较方式。

步骤:利用某个指定类实现Comparator接口,并且覆盖compare()方法,则此类会成为一个具备比较方法的类。在建立TreeSet的时候,将此类对象传入其中。

则此时,添加进TreeSet中的元素可按照指定比较方法进行排序。



下边举例演示俩种排序方式。

排序方式一:代码1:

package com.package1;

import java.util.*;

public class TreeSettest {

	public static void main(String[] args) {
//创建对象
TreeSet ts=new TreeSet(); //添加元素
ts.add("abcjjj");
ts.add("abb");
ts.add("daccc");
ts.add("gfg");
ts.add("geee");
ts.add("r"); //进行迭代
Iterator it=ts.iterator(); //循环取出元素
while(it.hasNext())
{
System.out.println(it.next());
} } }

输出结果如下:

abb

abcjjj

daccc

geee

gfg

r

由此可见,此时元素具备可比性,即按照其自然顺序进行排序。打开帮助文档,我们可以清晰的发现String已经实现了Comparable接口,并且已经覆盖了compareTo(),“这不是废话么^_^”,如图所示:







ps……如果我们要往TreeSet里添加的元素是自己刚刚定义的,我们也可以自己定义该元素的类实现Comparator接口,并且覆盖compareTo()方法,如下所示:代码2:

package com.package1;

import java.util.*;

class Student implements Comparable//该接口强制让学生具备比较性。
{
private String name;
private int age; Student(String name,int age)
{
this.name = name;
this.age = age;
} public int compareTo(Object obj)
{ //return 0; if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student s = (Student)obj; //System.out.println(this.name+"....compareto....."+s.name);
if(this.age>s.age)
return 1;
if(this.age==s.age)
{
return this.name.compareTo(s.name);
}
return -1;
/**/
} public String getName()
{
return name; }
public int getAge()
{
return age;
}
}
public class TreeSet2
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet(); ts.add(new Student("lisi02",22));
ts.add(new Student("lisi02",21));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi06",18));
ts.add(new Student("lisi06",18));
ts.add(new Student("lisi007",29));
//ts.add(new Student("lisi007",20));
//ts.add(new Student("lisi01",40)); Iterator it = ts.iterator();
while(it.hasNext())
{
Student stu = (Student)it.next();
System.out.println(stu.getName()+"..."+stu.getAge());
}
}
}

结果如下:

lisi06...18

lisi09...19

lisi007...20

lisi02...21

lisi02...22

lisi007...29

此例子将学生元素,强行按照年龄来排序,这就是我们想要的排序方式。



第二种排序如下:

还是刚刚代码1的例子,我们使用第二种排序方式,使得String类型的元素按照长度来排序。

代码3:

/*
* 使元素按照长度来排序,若长度相同,则按照自然排序。
*/
public class TreeSettest { public static void main(String[] args) {
//创建对象
TreeSet ts=new TreeSet(new MyCompare()); //添加元素
ts.add("abc");
ts.add("bcc");
ts.add("das");
ts.add("bcde");
ts.add("asdfg");
ts.add("befqfca"); //进行迭代
Iterator it=ts.iterator(); //循环取出元素
while(it.hasNext())
{
System.out.println(it.next());
} } } //定义一个类实现Comparator接口,并且覆盖compare()方法。
class MyCompare implements Comparator
{ @Override
public int compare(Object o1, Object o2) {
//进行强制类型转换
String s1=(String) o1;
String s2=(String) o2; //进行比较
if(s1.length()>s2.length())
return 1;
if(s1.length()<s2.length())
return -1;
if(s1.length()==s2.length())
{
return s1.compareTo(s2);
}
return 0;
}
}

结果如下:

abc

bcc

das

bcde

asdfg

befqfca

此种情况下,我们不方便修改源代码,而只需要修改比较方法时,我们就可以自己创建一个比较器。在建立TreeSet时,将比较器传入即可使元素按照特定比较方式输出。

总结:

Comparable(方式一)接口和Compartor(方式二)接口的比较:

两种方法各有优劣, 用Comparable 简单, 只要实现Comparable 接口的对象直接就成为一个可以比较的对象,但

是需要修改源代码。

用Comparator 的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把

比较器和对象一起传递过去就可以比大小了, 并且在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其

可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。

















Java集合框架—Set的更多相关文章

  1. Java集合框架List,Map,Set等全面介绍

    Java集合框架的基本接口/类层次结构: java.util.Collection [I]+--java.util.List [I]   +--java.util.ArrayList [C]   +- ...

  2. Java集合框架练习-计算表达式的值

    最近在看<算法>这本书,正好看到一个计算表达式的问题,于是就打算写一下,也正好熟悉一下Java集合框架的使用,大致测试了一下,没啥问题. import java.util.*; /* * ...

  3. 【集合框架】Java集合框架综述

    一.前言 现笔者打算做关于Java集合框架的教程,具体是打算分析Java源码,因为平时在写程序的过程中用Java集合特别频繁,但是对于里面一些具体的原理还没有进行很好的梳理,所以拟从源码的角度去熟悉梳 ...

  4. Java 集合框架

    Java集合框架大致可以分为五个部分:List列表,Set集合.Map映射.迭代器.工具类 List 接口通常表示一个列表(数组.队列.链表 栈),其中的元素 可以重复 的是:ArrayList 和L ...

  5. Java集合框架之map

    Java集合框架之map. Map的主要实现类有HashMap,LinkedHashMap,TreeMap,等等.具体可参阅API文档. 其中HashMap是无序排序. LinkedHashMap是自 ...

  6. 22章、Java集合框架习题

    1.描述Java集合框架.列出接口.便利抽象类和具体类. Java集合框架支持2种容器:(1) 集合(Collection),存储元素集合 (2)图(Map),存储键值对.

  7. Java集合框架实现自定义排序

    Java集合框架针对不同的数据结构提供了多种排序的方法,虽然很多时候我们可以自己实现排序,比如数组等,但是灵活的使用JDK提供的排序方法,可以提高开发效率,而且通常JDK的实现要比自己造的轮子性能更优 ...

  8. (转)Java集合框架:HashMap

    来源:朱小厮 链接:http://blog.csdn.net/u013256816/article/details/50912762 Java集合框架概述 Java集合框架无论是在工作.学习.面试中都 ...

  9. Java集合框架

    集合框架体系如图所示 Java 集合框架提供了一套性能优良,使用方便的接口和类,java集合框架位于java.util包中, 所以当使用集合框架的时候需要进行导包. Map接口的常用方法 Map接口提 ...

  10. Java集合框架(常用类) JCF

    Java集合框架(常用类) JCF 为了实现某一目的或功能而预先设计好一系列封装好的具有继承关系或实现关系类的接口: 集合的由来: 特点:元素类型可以不同,集合长度可变,空间不固定: 管理集合类和接口 ...

随机推荐

  1. wamp + wordpress 安装

    WAMP是一个windows上的php开发集成环境,一键安装php,apache和mysql,非常方便. 双击wampserver2.2exxxxxxxxxx.exe文件进行安装,安装过程中直接下一步 ...

  2. Maven项目实战(1)

    一.maven的好处? 同样的项目使用maven工程来实现,它的项目源码很小: 1.依赖管理 就是对jar 包管理的过程 2.项目的一键构建 (编译-----测试----- 运行 --打包------ ...

  3. sublime Text3支持vue高亮,sublime Text3格式化Vue

    第一:让sublime Text3支持Vue高亮 PS:我的sublime版本是3126,我不清楚其它版本的是不是这样设置,不过可以看看思路自己摸索下 1.下载可以让vue格式高亮的插件vue-syn ...

  4. Uncommon Words from Two Sentences

    https://leetcode.com/problems/uncommon-words-from-two-sentences We are given two sentences A and B.  ...

  5. 5、opencv中的绘图函数

    1.目标 a.学习使用 OpenCV 绘制不同几何图形 b. 你将会学习到这些函数: cv2.line(), cv2.circle(), cv2.rectangle(),cv2.ellipse(),c ...

  6. HDU - 6025 Coprime Sequence(gcd+前缀后缀)

    Do you know what is called ``Coprime Sequence''? That is a sequence consists of nnpositive integers, ...

  7. ABP 软删除ISoftDelete

    一.简介 ABP 的软删除是为了,在删除的时候,不是真正的删除数据,是为了保护数据. 二.具体实现 在 Core  层,我们需要这个实体去实现这个 ISoftDelete 接口.实现它的 public ...

  8. 初探 Nginx 架构

    转载自:http://wiki.jikexueyuan.com/project/nginx/nginx-framework.html Nginx 在启动后,在 unix 系统中会以 daemon 的方 ...

  9. 洛谷P2194 HXY烧情侣

    题目描述 众所周知,\(HXY\)已经加入了\(FFF\)团.现在她要开始喜\((sang)\)闻\((xin)\)乐\((bing)\)见\((kuang)\)地烧情侣了.这里有\(n\)座电影院, ...

  10. appium desktop连接模拟器

    1.adb准备好,我建议,下载Androidstudio,因为这样adb是最新的,可能会避免很多问题 2.adb connect 127.0.0.1:xxxx (网易mumu是7555,别的模拟器自行 ...