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 ...
随机推荐
- ArcGIS Server注册地理数据库报machine:机器名[Oracle:(null)]错误的修改
环境介绍:本机安装了ArcGIS Server10.2,ArcGIS Desktop10.2,64位Oracle11g以及Oracle32位客户端.直连和服务连接都能成功. 问题:我要进行服务发布的时 ...
- iOS-UITextField-通知
二.处理文本框与键盘之间的关系(当键盘弹出遮挡到文本框的时候进行调整) 原理: 首先要明白: 1,键盘隐藏的时候,键盘上边界紧贴屏幕最低端,键盘在屏幕正下方. 2:键盘弹起的时候,键盘下边界跟屏幕下边 ...
- 浅析I/O模型及其设计模式
前言 I/O在软件开发中的重要性无需多言,无论是在操作系统.网络协议.DBMS这种底层支撑软件还是在移动APP,大型网站服务器等应用软件的开发中都是最核心最重要的部分.特别是现在软件服务使用量和数据量 ...
- EFcodeFirst+T4=操纵任意数据库
之前有写过两篇,EF选择Mysql数据源 跟 EF添加ADO.NET实体模型处直接选择Oracle数据源,其方便之处就不多说了,使用DBfirst直接点点点就能与数据库双向更新,而且关键是方便我们使用 ...
- SqL数据库发布订阅非聚集索引没有被复制到订阅服务器的解决方案
Non-Clustered Indexes not copying in Transactional Replication : SQL Server 2008 方法1: You have trans ...
- C#中dategridview数据导出为excel文件
先从数据库中获取数据,绑定在datagridview中,再从dategridview中导出为excel文件 1.新建窗体,把控件datagridview和按钮设置好,如图
- 用于dbnull的数据转换。因为用convert.to无法转换dbnull类型
/// <summary> /// add by wolf /// </summary> public static class ExtendObject { public s ...
- UGUI之Toggle使用
Toggle对象是一个开关.一般用于单选,可以用Toggle制作背包的选项卡 在场景中创建Toggle按钮.看看他有Toggle组件
- PHP simplexml_load_string 过滤<![CDATA[XXXX]]>
首先说说过滤<![CDATA[XXXX]]>干嘛用的. 这东西主要是防止XML里面嵌套HTML标签导致XML样式错乱的. 过滤很简单: $response = str_replace( a ...
- ASP.NET Core1.0 带来的新特性
1.采用新的文件系统,不再通过工程文件(.sln和.csproj)来定义项目文件清单. 解决方案文件还是*.sln,但项目文件变成*.xproj了.在项目文件夹下新增的文件会被自动添加到项目中,不用再 ...