首页 > 学院 > 开发设计 > 正文

JAVA基础学习day15--集合二TreeSet和泛型

2019-11-14 15:33:57
字体:
来源:转载
供稿:网友

一、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());        }    }}

 

结果:

Dcaaahabcbcacda

 

示例二、使用对象

 

二、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

 

方法摘要
intcompareTo(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:4print:heheshow:helloprint: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:heheprint:dfsdsprint:2323.3static:ffffstatic: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...23abc2...13abc3...33abc--1...23abc--2...13abc--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...13abc--3...33abc--5...23

 


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表