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 ...
随机推荐
- Python--matplotlib绘图可视化知识点整理
from:https://segmentfault.com/a/1190000005104723 本文作为学习过程中对matplotlib一些常用知识点的整理,方便查找. 强烈推荐ipython无论你 ...
- MyBatis知多少(10)应用程序数据库
应用程序数据库往往是最小.最简单.也最易于使用的数据库.这种数据库往往是我们这些开发人员通常不介意使用甚至非常乐意使用的.应用程序数据库通常与我们的应用程序处于同一个项目中,两者一齐设计和实现.正是因 ...
- MyBatis知多少(8)关系型数据库
MyBatis的存在就是为了简化对关系数据库的访问.数据库的确非常复杂,要正确地使用它们需要做很多的工作.数据库负责管理数据和修改数据.我们使用数据库而不简简单单地使用一个 平板文件的原因就在于数据库 ...
- AC_Dream 1224 Robbers(贪心)
题意:n个抢劫犯分别抢到的金钱是k1, k2, k3,...,一共得到的金钱是m, 但是在分钱的时候是按照x1/y, x2/y, x3/y,....的比例进行分配的!这样的话 一些抢劫犯就会觉得不公平 ...
- [Math] A love of late toward Mathematics - how to learn it?
Link: https://www.zhihu.com/question/19556658/answer/26950430 王小龙 ,数学,计算机视觉,图形图像处理 数学系博士怒答! 我想大家 ...
- 阅读Nosql代码有感
这一年总得来说,读书的时间不多.一是因为时间啥关系,这一年一直在跟着项目走,或者被项目牵着走,几乎所有的时间和精力全部被拴在几个项目上:不过所幸今年创业失败,又回去上班了,时间相对空余了一些. 双十一 ...
- UWP开发入门(十六)——常见的内存泄漏的原因
本篇借鉴了同事翔哥的劳动成果,在巨人的肩膀上把稿子又念了一遍. 内存泄漏的概念我这里就不说了,之前<UWP开发入门(十三)——用Diagnostic Tool检查内存泄漏>中提到过,即使有 ...
- Lambda表达式和匿名内部类(I)
本文git地址 前言 Java Labmda表达式的一个重要用法是简化某些匿名内部类(Anonymous Classes)的写法.实际上Lambda表达式并不仅仅是匿名内部类的语法糖,JVM内部是通过 ...
- 0422 发现( 数学口袋精灵)bug
团队博客地址: 甘佳萍:http://www.cnblogs.com/gjpg/ 李鹏飞:http://www.cnblogs.com/l549023320/ 赵创佳:http://www.cnblo ...
- JS 数组去重(数组元素是对象的情况)
js数组去重有经典的 几种方法 但当数组元素是对象时,就不能简单地比较了,需要以某种方式遍历各值再判断是否已出现. 因为: 1.如果是哈希判断法,对象作哈希表的下标,就会自动转换成字符型类型,从而导致 ...