集合框架 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. C++与UnrealScript脚本交互

    转自:http://m.blog.csdn.net/blog/qweewqpkn/39932499 一.c++调用uc脚本中的函数 举例: 1. 在脚本MenuManager.uc文件中实现函数: e ...

  2. XCode工程中 Project 和 Targets区别

    转自:http://blog.csdn.net/zhaozy55555/article/details/8557175 project就是一个项目,或者说工程,一个project可以对应多个targe ...

  3. NancyFX 第二章 Rest框架

    正如你看到的,Nancy有两个主要用途. 其中第一项是作为一种通用的基于 REST 框架,可替代 ASP.NET Web API 或其他Rest工具包. 默认情况下,Nancy提供一流的路由和内容协商 ...

  4. java——类的封装

    public void setName(String str) { name=str; } public void setAge(int a) //set方法需要在括号中定义数据类型 { if(a&g ...

  5. POJ-3669

    Meteor Shower Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 21055   Accepted: 5499 De ...

  6. K-S Test

    K-S test, test for the equality of continuous, one-dimensional probability distribution that can be ...

  7. CentOS6下安装Java jdk1.7.0_10和 maven

    安装步骤如下: 1. 下载JDK7.0_10 (jdk-7u10-linux-i586.tar.gz) 地址: 2. 卸载系统自带的开源JDK 查看是否安装JDK rpm -qa | grep jav ...

  8. windows和Dos常见命令总结

    linux最常见命令 (1) pwd命令pwd (即print working directory,打印工作路径) 命令的功能是显示当前的工作路径.如现在是在“/home/CAI”目录下,则可以用此命 ...

  9. [nyoj]会场安排问题-贪心

    会场安排问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 学校的小礼堂每天都会有许多活动,有时间这些活动的计划时间会发生冲突,需要选择出一些活动进行举办.小刘的工 ...

  10. 【微信小程序】开发实战 之 「数据缓存API」解析

    每个小程序都可以有自己的本地缓存,可以通过 数据缓存的API 实现对本地缓存进行 设置.获取和清理.本地缓存最大为10M.localStorage是永久存储的,但我们不建议将关键信息都放在localS ...