JAVA基础学习(十五)--集合二--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);}/** 按照年龄大小排序,年龄相同按姓名排序*/@Overridepublic 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);}/** 按照年龄大小排序,年龄相同按姓名排序*/@Overridepublic 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>{/** 按姓名排序,如果姓名相同,按年龄排序*/@Overridepublic 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>{@Overridepublic 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>{@Overridepublic 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");//传入doublet.print(2323.3);//传入字符串t.method("ffff");//传入intt.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>{@Overridepublic 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());}}*///使用泛型Tpublic 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>{@Overridepublic int compare(Person p1, Person p2) {return p1.getName().compareTo(p2.getName());}} //结果: abc--2...13 abc--3...33 abc--5...23
JAVA基础学习(十五)--集合二--TreeSet和泛型相关推荐
- Java基础笔记-十五、集合类库(下)
泛型机制(熟悉) 通常情况下集合中可以存放不同类型的对象,是因为将所有对象都看做Object类型放入的,因此从集合中取出元素时也是Object类型,为了表达该元素真实的数据类型,则需要强制类型转换,而 ...
- Java 基础(十五)并发工具包 concurrent
本文目录: java.util.concurrent - Java 并发包简介 阻塞队列 BlockingQueue 数组阻塞队列 ArrayBlockingQueue 延迟队列 DelayQueue ...
- java基础学习(五)
一.数组 1.什么是数组? 数组:数组可以存放多个同一类型的数据.数组也是一种数据类型,是引用数据类型.即:数组就是一组数据 double[] hens = {2,3,4,5}: double[] 表 ...
- java基础第二十五天 数据库
1. mysql数据库基本操作 1.1 mysql.mysqladmin和mysqldump 1.1.1. mysql命令 mysql指令连接数据库连接数据库 mysql -h host_name - ...
- Java基础(十五)IO流---字符流(Reader、Writer)、字节流(InputStream、OutputStream)
IO流(应用广泛) 1.概念与三要素 本质是一套用于数据传输的机制 分类: 根据传输的方向(参照物–内存) 输入流:往内存传输数据 输出流:从内存往外传输数据 根据数据传输方式: 字符流:底层以字符形 ...
- Java多线程学习十五:公平锁和非公平锁,为什么要“非公平”?
什么是公平和非公平 公平锁 指的是按照线程请求的顺序,来分配锁: 非公平锁 指的是不完全按照请求的顺序,在一定情况下,可以允许插队.但需要注意这里的非公平并不是指完全的随机,不是说线程可以任意插队,而 ...
- 重学java基础第二十五课:数据类型
- 重学java基础第十五课:java三大版本
- Java基础学习——第十六章 Java8新特性
Java基础学习--第十六章 Java8 新特性 Java8(JDK8.0)较 JDK7.0 有很多变化或者说是优化,比如 interface 里可以有静态方法和默认方法,并且可以有方法体,这一点就颠 ...
最新文章
- 让 VAGRANT 启动并运行起来
- java进程与线程_Java多线程笔记(零):进程、线程与通用概念
- 如何确认mongodb数据插入是否成功_go连接mongodb
- Codeforces Round #481 (Div. 3)【完结】
- 13、mybatis多表关联查询级联属性
- 地图投影系列介绍(一)----地球空间模型
- css三栏布局技巧,CSS-三栏布局的常用6种方法
- 酷炫加特技的个人主页
- 智能一代云平台(二十一):生产环境Nginx报 502 Bad Gateway 问题复现及解决方案
- python是干什么的-python干嘛用
- OpenGL ES与EGL的关系(二十一)
- liunx查询进程下的线程
- 概率论 方差公式_概率论基本问题
- STM32嵌入式基础开发04-PS2手柄SPI通讯数据输出(4_SPI)
- hdoj2154跳舞毯
- 基因变异相关序列提取工具
- Unhandled exception in al.exe(KERNELBASE.DLL):0xE06D7363:Microsoft C++Exception
- 【Python基础学习】基本数据结构:列表、元组、栈、字典、集合与队列
- 帝国cms html5 编辑器,帝国CMS修改默认编辑器为百度编辑器UEditor的方法
- jquery plugin --image magnifier 放大器