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 ...
随机推荐
- scanf中的[]
今天被问到一个问题,如何用scanf将 hello-my-world中的三个单词, hello my world 分别放到三个char数组中去 于是用到了scanf中的[] [ ] 扫描字符集合,比如 ...
- 第一次接触终极事务处理——Hekaton
在这篇文章里,我想给出如何与终极事务处理(Extreme Transaction Processing (XTP) )的第一次接触,即大家熟知的Hakaton.如果你想对XTP有个很好的概况认识,我推 ...
- HTML简明教程(一)
HTML简明教程(一) 内容主体来自:W3School 一.HTML 简介 二.HTML 基础 三.HTML 元素 四.HTML 属性 五.HTML 标题 六.HTML 段落 七.HTML 文本格式化 ...
- 黑客入门之IP地址及常用命令
在网络上,只要利用IP地址就可以找到目标主机,因此,如果黑客想要攻击某个网络主机,就要先确定该目标主机的域名或IP地址. IP地址概述 所谓IP地址就是一种主机编址方式,给每个连接在Internet上 ...
- [ASP.NET]谈谈IIS与ASP.NET管道
作为一个Asp.Net平台开发者,非常有必要了解IIS和Asp.Net是如何结合,执行我们的托管代码,以及Asp.Net管道事件的. 本节目录 IIS 5.X IIS 6 IIS 7+ 集成模式 As ...
- Sprint第三个冲刺(第七天)
项目基本上可以说完成了,只是还有些小bug要修复.
- 11.22 点餐APP第一阶段总结
第一个冲刺结束了,任务也算是完成了. 团队合作不像单独做那样想怎么来就怎么来,各个人都不同的意见,最后方案的需要每个人一致同意通过才能执行. 不过团队合作分配到每个人的任务也相对轻一点,而且遇到问题解 ...
- Scrum团队
5.Scrum团队成立 5.1 团队名称,团队目标.团队口号.团队照: 团队名称:@four! 团队目标:做出像“数学口袋精灵”那么棒的软件 团队口号:多劳多得 团队照: 5.2 角色分配 产品负责人 ...
- Asp.Net 三层架构之泛型应用
一说到三层架构,我想大家都了解,这里就简单说下,Asp.Net三层架构一般包含:UI层.DAL层.BLL层,其中每层由Model实体类来传递,所以Model也算是三层架构之一了,例外为了数据库的迁移或 ...
- Winform屏幕截图保存C#代码
代码如下: using System.Runtime.InteropServices; using System.Drawing.Imaging; [System.Runtime.InteropSer ...