Fork me on GitHub

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

 

posted @ 2015-09-25 10:10  森林森  阅读(1003)  评论(0编辑  收藏  举报