zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    tuple-1
    禅语-1
    综述的写作技巧-1
    皆大欢喜组合
    类和对象-3
    双棍练习
    CodeBlocks开发环境使用-1
    类和对象-2
    类和对象-1
    13-归并排序-分治策略应用于排序
  • 原文地址:https://www.cnblogs.com/liunanjava/p/4830988.html
Copyright © 2011-2022 走看看