你的位置:首页 > Java教程

[Java教程]JAVA基础学习day15


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