JAVA基础学习day15--集合二 TreeSet和泛型
一、TreeSet
1.1、TreeSet
Set:hashSet:数据结构是哈希表。线程是非同步的。
保证元素唯一性的原理:判断元素的HashCode值是否相同。
如果相同,还会判断元素的equals方法是否为true;
TreeSet: 可以去Set集合中的元素时行 排序。
使用二叉树的数据结构。
保证元素唯一性的依据:compareTo()方法return 0
使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。
示例一、
package com.pb.treeset.demo1; import java.util.Iterator;
import java.util.TreeSet; /**
*
* @author Denny
* TreeSet
* 可以对Set集合的元素进行自然排序
*
*/
public class TreeSetDemo1 { public static void main(String[] args) {
TreeSet ts=new TreeSet();
ts.add("abc");
ts.add("aah");
ts.add("cda");
ts.add("bca");
ts.add("Dca");
for(Iterator it=ts.iterator();it.hasNext();){
System.out.println(it.next());
} } }
结果:
Dca
aah
abc
bca
cda
示例二、使用对象
二、Comparable
TreeSet排序:
第一种方式,让元素自身具备比较性,元素实现Comparable接口,重写compareTo()方法。自然顺序排序
2.1、Comparable接口
public interface Comparable<T>
此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。
使用TreeSet存多个对象时,要在该对象类中实现Comparable接口,以实现TreeSet的排序,不然就会报java.lang.ClassCastException:
cannot be cast to java.lang.Comparable
| 方法摘要 | |
|---|---|
int |
compareTo(T o) 比较此对象与指定对象的顺序。 |
-
- 参数:
o- 要比较的对象。- 返回:
- 负整数、零或正整数,根据此对象是小于、等于还是大于指定对象。
- 抛出:
ClassCastException- 如果指定对象的类型不允许它与此对象进行比较。
排序时:当主要条件相同时,要判断次要条件。
package com.pb.treeset.demo1;
public class Person implements Comparable{
private String name;//姓名
private int age;//年龄
private String gender;//性别
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name, int age, String gender) {
super();
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
//显示所有属性
public void show(){
System.out.println("姓名:"+this.name+"........年龄:"+this.age+"...........性别:"+this.gender);
}
/*
* 按照年龄大小排序,年龄相同按姓名排序
*/
@Override
public int compareTo(Object obj) {
if(!(obj instanceof Person)){
try {
throw new Exception("不是人类对象");
} catch (Exception e) {
e.printStackTrace();
}
}
Person p=(Person)obj;
if(this.age>p.age){
return 1;
}else if(this.age<p.age){
return -1;
}else{
return this.name.compareTo(p.name);
}
}
}
package com.pb.treeset.demo1; import java.util.Iterator;
import java.util.TreeSet; public class TreeSetDemo2 { public static void main(String[] args) {
Person p1=new Person("lisi007",19,"man");
Person p2=new Person("lisi003",20,"woman");
Person p3=new Person("zhangsan002",19,"man");
Person p4=new Person("abc009",20,"woman");
Person p5=new Person("ndd011",19,"man");
Person p6=new Person("qq005",16,"woman");
//声明TreeSet集合
TreeSet<Person>ts=new TreeSet<Person>();
//添加对象元素
ts.add(p1);
ts.add(p2);
ts.add(p3);
ts.add(p4);
ts.add(p5);
ts.add(p6);
//遍历
for(Iterator<Person> it=ts.iterator();it.hasNext();){
Person p=it.next();
p.show();
}
} }
结果:
姓名:qq005........年龄:16...........性别:woman
姓名:lisi007........年龄:19...........性别:man
姓名:ndd011........年龄:19...........性别:man
姓名:zhangsan002........年龄:19...........性别:man
姓名:abc009........年龄:20...........性别:woman
姓名:lisi003........年龄:20...........性别:woman
示例:如果按存入顺序取出只需要CompareTo方法return 1
package com.pb.treeset.demo1;
public class Person implements Comparable{
private String name;//姓名
private int age;//年龄
private String gender;//性别
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name, int age, String gender) {
super();
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
//显示所有属性
public void show(){
System.out.println("姓名:"+this.name+"........年龄:"+this.age+"...........性别:"+this.gender);
}
/*
* 按照年龄大小排序,年龄相同按姓名排序
*/
@Override
public int compareTo(Object obj) {
//存出顺序
return 1;
//倒序
//return -1
//如果返回0就只有一个元素
}
}
三、
3.1、实现指定的比较器实现Comparator 接口,重写compare方法
第二种方式:当元素自身不具备比较性时或者具备的比较性不是所需要的。
这里就需要让集合自身具备比较性。
在集合初始化,就有了比较方式。
| 构造方法摘要 | |
|---|---|
TreeSet() 构造一个新的空 set,该 set 根据其元素的自然顺序进行排序。 |
|
TreeSet(Collection<? extends E> c)构造一个包含指定 collection 元素的新 TreeSet,它按照其元素的自然顺序进行排序。 |
|
TreeSet(Comparator<? super E> comparator)构造一个新的空 TreeSet,它根据指定比较器进行排序。 |
|
TreeSet(SortedSet<E> s)构造一个与指定有序 set 具有相同映射关系和相同排序的新 TreeSet。 |
|
定义比较器,将比较器对象 作为参数转递给集合TreeSet的构造方法
示例一、
package com.pb.treeset.demo2;
public class Person{
private String name;//姓名
private int age;//年龄
private String gender;//性别
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name, int age, String gender) {
super();
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
//显示所有属性
public void show(){
System.out.println("姓名:"+this.name+"........年龄:"+this.age+"...........性别:"+this.gender);
}
}
比较器
package com.pb.treeset.demo2; import java.util.Comparator;
/**
* 比较器,实现Comparator接口,
* 并重写compare方法
* @author Administrator
*
*/
public class MyComparetor implements Comparator<Person>{ /*
* 按姓名排序,如果姓名相同,按年龄排序
*/
@Override
public int compare(Person p1, Person p2) {
//比较姓名
int num=p1.getName().compareTo(p2.getName());
//如果姓名相同
if(num==0){
//比较年龄
return new Integer(p1.getAge()).compareTo(new Integer(p2.getAge()));
}
//返回结果
return num;
} }
package com.pb.treeset.demo2; import java.util.Iterator;
import java.util.TreeSet; public class TreeSetDemo3 { public static void main(String[] args) {
//声明TreeSet集合,并将比较器传入构造方法
TreeSet<Person> ts=new TreeSet<Person>(new MyComparetor());
//添加元素
ts.add(new Person("lisi010",21,"man"));
ts.add(new Person("lisi010",19,"man"));
ts.add(new Person("lisi007",21,"woman"));
ts.add(new Person("lisi002",16,"man"));
ts.add(new Person("lisi022",21,"woman"));
ts.add(new Person("lisi010",16,"man"));
//遍历
for(Iterator<Person> it=ts.iterator();it.hasNext();){
Person p=it.next();
p.show();
} } }
姓名:lisi002........年龄:16...........性别:man
姓名:lisi007........年龄:21...........性别:woman
姓名:lisi010........年龄:16...........性别:man
姓名:lisi010........年龄:19...........性别:man
姓名:lisi010........年龄:21...........性别:man
姓名:lisi022........年龄:21...........性别:woman
示例二、
package com.pb.treeset.demo2; import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet; /*
* 按照字符串长度排序
*/
public class TreeSetDemo4 { public static void main(String[] args) {
TreeSet<String> ts=new TreeSet<String>(new MyCompare());
ts.add("abcd");
ts.add("cc");
ts.add("cba");
ts.add("Cba");
ts.add("z");
ts.add("NBA");
ts.add("hehe");
ts.add("A");
for(Iterator<String> it =ts.iterator();it.hasNext();){
System.out.println(it.next());
} } }
/*
* 比较器
*/
class MyCompare implements Comparator<String>{ @Override
public int compare(String s1, String s2) {
//比较长度
int len=new Integer(s1.length()).compareTo(new Integer(s2.length()));
//如果长度相同,比较内容
if(len==0){
return s1.compareTo(s2);
}
return len; } }
四、泛型
4.1、泛型概述
JDK1.5出现新特性,用于解决安全问题,是一个安全机制
如:ArrayList<String> a1=new ArrayList<String>();
声明一个字符串类型的arraylist容器,只能存String类型
优点:将运行时期出现的问题ClassCastException,转移到了编译时期。
方便程序员解决问题,让运行时问题送减少,同时安全。
避免了强制类型转换麻烦。
package com.pb.fanxing.demo1; import java.util.ArrayList;
import java.util.Iterator; public class ArryListDemo1 { public static void main(String[] args) {
//声明一个Arraylist集合,只能存放String类型
ArrayList<String> al=new ArrayList<String>();
al.add("abcd");
al.add("adc");
al.add("NBA");
al.add("CFO");
//遍历
Iterator<String> it=al.iterator();
while(it.hasNext()){
String str=it.next();
System.out.println(str);
} } }
五、泛型使用
5.1、使用泛型
通过<>来定义泛型
通常在集合框架中很常见,只要见到<>就要定义泛型。
其它泛型<>就是用来接收类型的。
当使用集合时,将集合要存储的数据类型作为参数传递到<>中.
package com.pb.fanxing.demo1; import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
//倒序排列 public class Demo2 { public static void main(String[] args) {
TreeSet<String> ts=new TreeSet<String>(new MyCompare());
ts.add("abcd");
ts.add("cc");
ts.add("cba");
ts.add("Cba");
ts.add("z");
ts.add("NBA");
ts.add("hehe");
ts.add("A");
for(Iterator<String> it =ts.iterator();it.hasNext();){
System.out.println(it.next());
} } }
/*
* 比较器
*/
class MyCompare implements Comparator<String>{ @Override
public int compare(String s1, String s2) {
//比较长度
//倒序排列
int len=new Integer(s2.length()).compareTo(new Integer(s1.length()));
//如果长度相同,比较内容
if(len==0){
return s2.compareTo(s1);
}
return len; }
}
hehe
abcd
cba
NBA
Cba
cc
z
A
六、泛型类
6.1、泛型类的使用
package com.pb.fanxing.demo2;
/**
* 当类中要操作的引用数据类型不确定的时候
* 早期定主Object来完成扩展
* 现在定义泛型来完成扩展
*
*/
class Person{
private String name;
private int age;
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
} }
class Student extends Person{
private int id; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} }
/*
* 泛型类
*/
class Utils<T>{ private T t;
public void setT(T t){
this.t=t;
}
public T getT(){
return t;
}
} public class GenericDemo1 { public static void main(String[] args) {
Utils<Person> u=new Utils<Person>();
u.setT(new Person("张三",23));
Person person=u.getT();
System.out.println(person.getName()+"......"+person.getAge()); } }
泛型类定义的泛型,在整个类中有效,如果被方法使用
泛型类的对象明克要操作的具体类型后,所有 要操作的类型已经固定
七、泛型方法
7.1、泛型类的方法
为了让不同方法可以操作不同类型,而且类型还不确定,
可以将泛型定义在方法上
package com.pb.fanxing.demo2; /**
* 泛型方法
*
*/
class Demo{
public<T> void show(T t){
System.out.println("show:"+t);
}
public <T> void print(T t){
System.out.println("print:"+t);
}
} public class GenericDemo2 { public static void main(String[] args) {
Demo d=new Demo();
d.show(4);
d.print("hehe");
d.show("hello");
d.print(3.4); } }
结果:
show:4
print:hehe
show:hello
print:3.4
八、静态泛型方法
8.1、静态泛型方法
静态方法不可以访问类上定义的泛型。
如果静态方法访问的类型不确定,可以将泛型定义在方法上
package com.pb.fanxing.demo2;
class Tool<T>{
//和类上的泛型一至
public<T> void show(T t){
System.out.println("show:"+t);
}
//单独的和类上的不一样,但也可以使用类上的
public <Q> void print(Q q){
System.out.println("print:"+q);
}
//单独的和类上的不一样因为是static的,不能和类上的一样
public static<W> void method(W t){
System.out.println("static:"+t);
}
}
public class GenericStaticDemo {
public static void main(String[] args) {
//定义字符串
Tool<String> t=new Tool<String>();
//传入字符串
t.show("hehe");
//传入字符串
t.print("dfsds");
//传入double
t.print(2323.3);
//传入字符串
t.method("ffff");
//传入int
t.method(222);
}
}
结果:
show:hehe
print:dfsds
print:2323.3
static:ffff
static:222
九、泛型接口
9.1、泛型接口
package com.pb.fanxing.demo2;
interface Test<T>{
public void show(T t);
}
class TestImpl<T> implements Test<T>{
@Override
public void show(T t) {
System.out.println(t);
}
}
public class GenericDemo3 {
public static void main(String[] args) {
Test<String> test=new TestImpl<String>();
test.show("hello");
Test<Integer> test1=new TestImpl<Integer>();
test1.show(332);
}
}
十、泛型限定
10.1、泛型限定
使用<?>来占位
package com.pb.fanxing.demo2; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; public class GenericDemo4 { public static void main(String[] args) {
List<String> list=new ArrayList<String>();
list.add("aa");
list.add("ab");
list.add("ac");
List<Integer> list1=new ArrayList<Integer>();
list1.add(3);
list1.add(1);
list1.add(5);
print(list);
print(list1); }
/*public static void print(List<?> list){ //不确定类型
Iterator<?> it=list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}*/
//使用泛型T
public static<T> void print(List<T> list){ //不确定类型
Iterator<T> it=list.iterator();
while(it.hasNext()){
T t=it.next(); //使用泛型可以操作对象
System.out.println(t);
}
}
}
aa
ab
ac
3
1
5
10.2、上限和下限
?:通配符,也可以理解为占位符。
泛型的限定
<? extends E>:可以接收E类型 或者E的子类 上限
<? super E> 可以接收E类型或者E的父类型。下限
package com.pb.fanxing.demo2; import java.util.ArrayList;
import java.util.Iterator; class Person{
private String name;
private int age;
public Person(String name,int age){
this.name=name;
this.age=age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
}
class Student extends Person{
public Student(String name,int age){
super(name,age);
}
}
public class GenericDemo5 { public static void main(String[] args) {
ArrayList<Person> a1=new ArrayList<Person>();
a1.add(new Person("abc1",23));
a1.add(new Person("abc2",13));
a1.add(new Person("abc3",33));
ArrayList<Student> a2=new ArrayList<Student>();
a2.add(new Student("abc--1",23));
a2.add(new Student("abc--2",13));
a2.add(new Student("abc--3",33)); print(a1);
print(a2); }
public static void print(ArrayList<? extends Person> list){//代表Person和Person的子类
Iterator<? extends Person> it=list.iterator();
while(it.hasNext()){
Person p=it.next();
System.out.println(p.getName()+"..."+p.getAge());
}
}
}
//结果
abc1...23
abc2...13
abc3...33
abc--1...23
abc--2...13
abc--3...33
下限
package com.pb.fanxing.demo2; import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet; class Person{
private String name;
private int age;
public Person(String name,int age){
this.name=name;
this.age=age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
}
class Student extends Person{
public Student(String name,int age){
super(name,age);
}
}
public class GenericDemo5 { public static void main(String[] args) {
TreeSet<Student> ts=new TreeSet<Student>(new MyCompare()); ts.add(new Student("abc--5",23));
ts.add(new Student("abc--2",13));
ts.add(new Student("abc--3",33)); print(ts); }
public static void print(Set<? extends Person> list){//代表Person和Person的子类
Iterator<? extends Person> it=list.iterator();
while(it.hasNext()){
Person p=it.next();
System.out.println(p.getName()+"..."+p.getAge());
}
}
}
class MyCompare implements Comparator<Person>{ @Override
public int compare(Person p1, Person p2) {
return p1.getName().compareTo(p2.getName());
} }
//结果: abc--2...13
abc--3...33
abc--5...23
JAVA基础学习day15--集合二 TreeSet和泛型的更多相关文章
- Java基础学习总结(二)
Java语言的特点: Java语言是简单的 Java语言是面向对象的 Java语言是跨平台(操作系统)的(即一次编写,到处运行) Java是高性能的 运行Java程序要安装和配置JDK jdk是什么? ...
- JAVA基础学习day20--IO流二-缓冲流、字节流
一.缓冲流 1.1.字符流的缓冲区 缓冲区的出现是为了提高IO的读写效率 对应类 BufferedReader BufferedWriter 缓冲区要结合流才可以使用 在流的基础上对流的功能进行了增强 ...
- Java基础学习笔记十二 类、抽象类、接口作为方法参数和返回值以及常用API
不同修饰符使用细节 常用来修饰类.方法.变量的修饰符 public 权限修饰符,公共访问, 类,方法,成员变量 protected 权限修饰符,受保护访问, 方法,成员变量 默认什么也不写 也是一种权 ...
- java基础学习总结——线程(二)
一.线程的优先级别
- 转载-java基础学习汇总
共2页: 1 2 下一页 Java制作证书的工具keytool用法总结 孤傲苍狼 2014-06-24 11:03 阅读:25751 评论:3 Java基础学习总结——Java对象的序列化和 ...
- JAVA基础学习-集合三-Map、HashMap,TreeMap与常用API
森林森 一份耕耘,一份收获 博客园 首页 新随笔 联系 管理 订阅 随笔- 397 文章- 0 评论- 78 JAVA基础学习day16--集合三-Map.HashMap,TreeMap与常用A ...
- 尚学堂JAVA基础学习笔记
目录 尚学堂JAVA基础学习笔记 写在前面 第1章 JAVA入门 第2章 数据类型和运算符 第3章 控制语句 第4章 Java面向对象基础 1. 面向对象基础 2. 面向对象的内存分析 3. 构造方法 ...
- Java基础学习笔记总结
Java基础学习笔记一 Java介绍 Java基础学习笔记二 Java基础语法之变量.数据类型 Java基础学习笔记三 Java基础语法之流程控制语句.循环 Java基础学习笔记四 Java基础语法之 ...
- JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费者、线程池、匿名内部类使用多线程、定时器、面试题
JAVA基础再回首(二十五)--Lock锁的使用.死锁问题.多线程生产者和消费者.线程池.匿名内部类使用多线程.定时器.面试题 版权声明:转载必须注明本文转自程序猿杜鹏程的博客:http://blog ...
随机推荐
- `cocos2dx非完整` 开始自己的FW模块
上一篇的文章中说到了一些个人习惯的东西以及一些简单的项目配置,这一篇文章我们来进一步完善一些东西.首先,打开编译以后的客户端执行,会看到一大堆的fileutils加载luac文件的提示,在终端显示一大 ...
- [Design Patterns] 1. Primary concept & term - UML
It's time to review design patterns, especially when I reach the turning-point of my career. That's ...
- 15套帮助你展示 App 设计的透视屏幕原型素材
Dribbble 和 Behance 是最好两个展示你的设计作品的地方.现在流行使用透视屏幕来展示应用程序设计效果,尤其是在 Dribbble 上面,有众多高品质的免费资源和设计素材. 这篇文章汇集了 ...
- Xcode-快捷键大全
1. 文件CMD + N: 新文件CMD + SHIFT + N: 新项目CMD + O: 打开CMD + S: 保存CMD+OPt+S:保存所有文件CMD + SHIFT + S: 另存为CMD + ...
- [Tool] Visual Studio必备插件 + 技能
总结自己常用的VS插件,其中部分需要注册. 在该链接http://www.cnblogs.com/neverc/p/4591501.html中提供 1.Web Essentials(测试支持2010, ...
- 0406.复利计算器5.0版-release
复利计算器5.0-release 目录 项目简介 Github链接推送 客户需求 新增需求分析 项目设计 效果演示 操作说明 程序结构 结对分工 合作照片 总结 1.项目简介 项目名称:复利计算器 目 ...
- 统一者管理员指南(Unifier Administration Guide)中文
统一者管理员指南 Unifier Administration Guide 2014年6月 发布 2014年11月翻译 10.0版本 10.0.1译 关于译者 翻译者QQ:77811970 Email ...
- C# FTP远程服务器返回错误:(550) 文件不可用(例如,未找到文件,无法访问文件)
今天用代码删除FTP服务器上的目录时候,报错:远程服务器返回错误:(550) 文件不可用(例如,未找到文件,无法访问文件). 习惯性的google,不外乎以下几点: 1.URL路径不对,看看有没有多加 ...
- 调试报“The source file is different from when the module was built.”问题的解决
It is related to the checksums which is used to ensure that you are stepping in matching source. You ...
- Worm.Win32.DownLoader.ns病毒主进程新式输入法注入分析(IME Inject)
1.病毒会在system32目录生成一个以tmp结尾的随机数命名的文件. 2.然后挂钩HOOK本进程空间的imm32.dll导出的ImmLoadLayout函数和ntdll.dll导出的ZwQuery ...