黑马程序员——集合(二)

——- android培训java培训、期待与您交流! ———-

泛型

泛型: JDK1.5 版本一会出现的新特性。用于解决安全问题,是一个类型安全机制。

好处:
1,运行时期出现问题ClassCastException,转移到了编译时期。
方便于程序员解决问题。也让运行时期问题减少。
2,避免了强制转换的麻烦。

泛型格式: 通过<>来定义要操作的引用数据类型。

在使用java提供的对象时,什么时候写泛型呢?
通常在集合框架中很常见。
只要见到<>就要定义泛型。

其实<>就是用来接收类型的。
如:ArrayList al = new ArrayList();
当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可

代码示例:

/*
  泛型的使用
*/
import java.util.*;

public class Demo {
    public static void main(String[] args) {
        ArrayList<String> al = new ArrayList<String>();//明确集合的类型是String
        al.add("java01");
        al.add("java");
        al.add("java03sdf");
//      al.add(4);//此处不能执行,在编译时会出现异常,而不是在运行时才出现异常。将运行时异常转移到编译时异常

        Iterator<String> it = al.iterator();//明确迭代器的类型是String
        while(it.hasNext()){
            String s = it.next();//此处省略了强制转换,因为迭代器已经明确了类型是String
            print(s+" : "+s.length());

            /*
             结果:
                java01 : 6
                java : 4
                java03sdf : 9

             */
        }
    }

    public static void print(Object obj) {
        System.out.println(obj);
    }
}
/*
  需求:
    将字符串长度由小到大排序,并且使用泛型的方式
 */
import java.util.*;

public class Demo {
    public static void main(String[] args) {
        TreeSet<String> al = new TreeSet<String>(new MyComparator());

        //此方式是错的,ArrayList构造方法不能接收MyComparator对象
        //ArrayList<String> al = new ArrayList<String>(new MyComparator());

        al.add("sfdgsdfsfgg");
        al.add("fgsdfgfg");
        al.add("asfga");
        al.add("asfkk");

        Iterator<String> it = al.iterator();
        while(it.hasNext()){
            print(it.next());

            /*
             结果:
                asfga
                asfkk
                fgsdfgfg
                sfdgsdfsfgg
             */
        }
    }

    public static void print(Object obj) {
        System.out.println(obj);
    }
}
class MyComparator implements Comparator<String>{//Comparator也是泛型
    public int compare(String o1, String o2) {//注意,此处不是public int compare(Object o1, Object o2) 
        int num = new Integer(o1.length()).compareTo(new Integer(o2.length()));
        if(num == 0)
            return o1.compareTo(o2);
        return num;
    }
}

泛型类

代码示例:

/*
  泛型类。

  什么时候使用泛型类?
    当类中要操作的引用数据类型不确定的时候。
    在早期定义Object来操作不确定的引用数据类型完成扩展。
    现在定义泛型来完成扩展。

    在类中的方法操作的都是同一种类型时,那么可以将类定义为泛型类。如ArrayList集合中的方法,操作的都是同一种类型
 */
import java.util.*;

class Student{

}
class Worker{

}
//将此类定义为泛型类
class Tool<T>{
    private T t;
    public void setObject(T t){
        this.t = t;
    }
    public Object getObject(){
        System.out.println("获取到了");
        return t;
    }
}
public class Demo {
    public static void main(String[] args) {
        Tool<Student> t = new Tool<Student>();
        t.setObject(new Student());
//      t.setObject(new Worker());//此方法编译时异常,因为Tool类型Student,当传入Worker类型时编译会出现异常
        Student s = (Student) t.getObject();
    }
}

泛型类的局限性

代码示例:

/*
 * 演示泛型类的局限性
 *
 * 泛型类定义的泛型,在整个类中有效。如果泛型类的对象明确要操作的具体类型后,
 * 所有要操作的类型就已经固定了。
 */
import java.util.*;
class Person<T>{
    public void function(T t){
        System.out.println("function:"+t);
    }
    public void method(T t){
        System.out.println("method:"+t);
    }
}
public class Demo {
    public static void main(String[] args) {
        Person<String> p1 = new Person<String>();//定义泛型为String,那么方法中的参数,都已经固定为String了
        p1.function("haha");
//      p1.method(4);//此处编译失败,因为p1这个对象指定的类型为String,则里边的方法接收的参数也为String。如: p1这个对象中的方法为 public void function(String t){},这是局限性
        Person<Integer> p2 = new Person<Integer>();
        p2.method(4);
//      p2.function("haha");//编译失败,因为p2指定的类型为Integer,里边的方法接收的参数为Integer. 如:public void method(Integer t){},这是局限性
    }
}

泛型方法

代码示例:

/*
 * 为了让不同方法可以操作不同类型,而且类型还不确定。
 * 那么可以将泛型定义在方法上。
 */
import java.util.*;
class Person{
    public <T> void function(T t){
        System.out.println("function:"+t);
    }
    public <T> void method(T t){
        System.out.println("method:"+t);
    }
}
public class Demo {
    public static void main(String[] args) {
        Person p = new Person();
        p.function("haha");//不会编译错误。因为此方法为泛型方法。
                    //相当于public void function(String t){}
        p.method(5);//不会编译错误。因为此方法为泛型方法。
                    //相当于public void method(Integer t){}

    }
}

静态泛型方法代码示例:

/*
 * 特殊之处:
 *      静态方法不可以访问类上定义的泛型。
 *      如果静态方法操作的应用数据类型不确定,可以将泛型定义在静态方法上
 * 
 * 注意:泛型只能接受对象。如:
 *      public <T> void method(T t){
 *          System.out.println("method:"+t);
 *      }
 *      当传入一个正数5时,系统则执行自动装箱,泛型 T 的类型为Integer而不是int
 */
import java.util.*;
class Person<T>{
    public void function(T t){
        System.out.println("function:"+t);
    }
    public <T> void method(T t){
        System.out.println("method:"+t);
    }
//  public static void print(T t){//此方法不能执行,静态方法不可以访问类上的泛型,因为类上的泛型是随着对象的创建而加载的,而静态方法随着类加载,静态方法加载的比对象快
//  }
    public static <W> void print(W w){//此方法可以执行,因为是静态泛型方法
        System.out.println("print:"+w);
    }
}
public class Demo {
    public static void main(String[] args) {
        Person<String> p = new Person<String>();
        p.function("haha");
        //p.function(4);//编译失败,因为此方法为public void function(String t){}

        p.method("hehe");//此方法没有错误,因为是泛型类。public void method(String t){}
        p.method(6);//此方法没有错误,因为是泛型类。public void method(Integer t){}

        Person.print("haha");
        Person.print(5);
    }
}

泛型接口

代码示例:

/*
 * 泛型接口
 * 
 * 开发中一般不多见
 */
import java.util.*;
interface Inter<T>{
    void show(T t);
}
class Person<T> implements Inter<T>{//此处定义了泛型T,那么Person也要定义为泛型T,同时实现Inter的方法参数也为T
    public void show(T t) {
        System.out.println("Person show:"+t);
    }
}
class Student implements Inter<String>{//若此处定义了泛型类型为String类型,则Student类不用定义为泛型,同时实现Inter的方法参数为String。
    public void show(String t) {//因为接口泛型定义为String,那么此方法要能接收String类型的参数
        System.out.println("Student show"+t);
    }
}
public class Demo {
    public static void main(String[] args) {
        Person<Integer> p = new Person<Integer>();
        p.show(4);
//      p.show("haha");//编译失败,因为Person指定为Integer

        Student s = new Student();
        s.show("haha");
    }
}

通配符 ?(占位符)的使用

代码示例:

/*
  通配符的使用方式
*/
import java.util.*;
public class Demo {
    public static void main(String[] args) {
        ArrayList<String> al = new ArrayList<String>();
        al.add("java01");
        al.add("java02");
        al.add("java03");
        print(al);

        ArrayList<Integer> al1 = new ArrayList<Integer>();
        al1.add(4);
        al1.add(5);
        al1.add(6);
        print(al1);
    }
    public static void print(ArrayList<?> al){//ArrayList<?> al = new ArrayList<Integer>();,此处可以接收多种类型的ArrayList。
                        //如:ArrayList<?> al = new ArrayList<String>();此类型也可以接收
        Iterator<?> it = al.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
            //System.out.println(it.next().length());//此方法不可以使用,因为接收的类型不确定,length()是针对于字符串类型使用的
            /*
             结果:
                java01
                java02
                java03
                4
                5
                6
             */
        }
    }
}

泛型限定

泛型的限定。
? extends E:可以接收E类型或者E的子类型。 上限限定。
? super E:可以接收E类型或者E的父类型。 下限限定。

注意:

ArrayList<String> al = new ArrayList<Integer>();
这种方式是不允许的,因为泛型必须要保证左边等于右边。如:ArrayList<String> al = new ArrayList<String>();

代码示例:

/*
   泛型的上限演示:  ? extends E
*/
import java.util.*;
class Person{
    private String name;
    public Person(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}
class Student extends Person{
    public Student(String name) {
        super(name);
    }
}
public class Demo {
    public static void main(String[] args) {
        ArrayList<Person> al = new ArrayList<Person>();
        al.add(new Person("java01"));
        al.add(new Person("java02"));
        al.add(new Person("java03"));
        print(al);

        ArrayList<Student> al1 = new ArrayList<Student>();
        al1.add(new Student("java001"));
        al1.add(new Student("java002"));
        al1.add(new Student("java003"));
        //print(al1);//此处编译失败。相当于ArrayList<Person> al = new ArrayList<Student>()。
                //必须保证左右两边相等才行,如ArrayList<Student> al = new ArrayList<Student>();
    }
    public static void print(ArrayList<Person> al){//该方法的参数ArrayList<Person> al 只能接收Person类型
        Iterator<Person> it = al.iterator();
        while(it.hasNext()){
            System.out.println(it.next().getName());
            /*
             结果:
                java01
                java02
                java03
             */
        }
    }
}

将以上代码修改为通用的代码如下:

/*
   泛型的上限演示:  ? extends E
*/
import java.util.*;
class Person{
    private String name;
    public Person(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}
class Student extends Person{
    public Student(String name) {
        super(name);
    }
}
public class Demo {
    public static void main(String[] args) {
        ArrayList<Person> al = new ArrayList<Person>();
        al.add(new Person("java01"));
        al.add(new Person("java02"));
        al.add(new Person("java03"));
        print(al);

        ArrayList<Student> al1 = new ArrayList<Student>();
        al1.add(new Student("java001"));
        al1.add(new Student("java002"));
        al1.add(new Student("java003"));
        print(al1);
    }
    public static void print(ArrayList<? extends Person> al){//该方法的参数ArrayList<? extends Person> al  代表可以接收Person或者Person的子类型
        Iterator<? extends Person> it = al.iterator();
        while(it.hasNext()){
            System.out.println(it.next().getName());//调用了父类中的getName方法。如果集合接受的是子类,子类也可以调用此方法
            /*
             结果:
                java01
                java02
                java03
                java001
                java002
                java003
             */
        }
    }
}
/*
   泛型的下限演示:  ? super E
*/
import java.util.*;

class Person {//定义一个人
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

class Student extends Person {//学生继承了人
    public Student(String name) {
        super(name);
    }
}

class Worker extends Person {//工人也继承人
    public Worker(String name) {
        super(name);
    }
}

class WorkerComp implements Comparator<Worker>{//定义一个 专门比较工人 的比较器,将工人进行排序
    public int compare(Worker o1, Worker o2) {
        return o2.getName().compareTo(o1.getName());//倒序排序
    }
}
class StuComp implements Comparator<Student>{//定义一个 专门比较学生 的比较器,将学生进行排序
    public int compare(Student o1,Student o2){
        return o2.getName().compareTo(o1.getName());//倒序排序
    }
}
public class Demo {
    public static void main(String[] args) {
        TreeSet<Worker> ts = new TreeSet<Worker>(new WorkerComp());//将工人比较器传入工人集合的构造方法
        //TreeSet<Worker> t = new TreeSet<Worker>(new StuComp());//此方法不能执行,构造方法为:new TreeSet<Worker>(Comparator<? super Werker>),该构造方法只能接受Werker或者Werker的父类
        ts.add(new Worker("worker01"));
        ts.add(new Worker("worker02"));
        ts.add(new Worker("worker03"));
        Iterator<Worker> it = ts.iterator();
        while(it.hasNext())
            System.out.println(it.next().getName());
        /*
         结果:
            worker03
            worker02
            worker01
         */

        TreeSet<Student> ts1 = new TreeSet<Student>(new StuComp());//将学生比较器传入学生集合的构造方法
        //TreeSet<Student> t1 = new TreeSet<Student>(new WorkerComp());//此方法不能执行,构造方法为:new TreeSet<Student>(Comparator<? super Student>),该构造方法只能接受Student或者Student的父类
        ts1.add(new Student("student01"));
        ts1.add(new Student("student02"));
        ts1.add(new Student("student03"));
        Iterator<Student> it1 = ts1.iterator(); 
        while(it1.hasNext()){
            System.out.println(it1.next().getName());
            /*
             结果:
                student03
                student02
                student01
             */
        }
    }
}

修改上边的代码,新的代码如下

/*
   泛型的下限演示:  ? super E
*/

import java.util.*;

class Person {//人
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

class Student extends Person {//学生继承人
    public Student(String name) {
        super(name);
    }
}

class Worker extends Person {//工人继承人
    public Worker(String name) {
        super(name);
    }
}

class Comp implements Comparator<Person>{//此处可以接收Person的子类
    public int compare(Person o1, Person o2) {
        return o2.getName().compareTo(o1.getName());//倒序排序
    }
}

public class Demo {
    public static void main(String[] args) {
        TreeSet<Worker> ts = new TreeSet<Worker>(new Comp());//将 人 的比较器传入 工人 的构造方法。 new TreeSet<Worker>(Comparator<? super Worker>),可以接收Worker或者Worker的父类型
        ts.add(new Worker("worker01"));
        ts.add(new Worker("worker02"));
        ts.add(new Worker("worker03"));
        Iterator<Worker> it = ts.iterator();
        while(it.hasNext())
            System.out.println(it.next().getName());
        /*
         结果:
            worker03
            worker02
            worker01
         */

        TreeSet<Student> ts1 = new TreeSet<Student>(new Comp());//将 人 的比较器传入 学生 的构造方法。 new TreeSet<Student>(Comparator<? super Student>),可以接收Student或者Student的父类型
        ts1.add(new Student("student01"));
        ts1.add(new Student("student02"));
        ts1.add(new Student("student03"));
        Iterator<Student> it1 = ts1.iterator(); 
        while(it1.hasNext()){
            System.out.println(it1.next().getName());
            /*
             结果:
                student03
                student02
                student01
             */
        }
    }
}

Map集合

Map集合: 该集合存储键值对。一对一对往里存。而且要保证键的唯一性。

    1,添加
        <V> value = map.put(K key,V value);         返回被覆盖的value值,如果没有被覆盖,返回null
        putAll(Map<? extends K,? extends V> m);
    2,删除    
        clear();                        清空集合
        <V> value = map.remove(Object key);         删除某个键
    3,判断
        boolean b = map.containsValue(Object value);        判断map集合是否包含值
        boolean b = map.containsKey(Object key);        判断map集合是否包含键
        boolean b = map.isEmpty();              判断集合是否为空
    4,获取
        <V> value = map.get(Object key);            获取某个键中的值
        int l = map.size();                 获取集合中元素个数
        Collection<V> coll = map.values();          获取集合中所有的值

        Set<Map.Entry<K,V>> entrySet = map.entrySet();      获取Map集合中的映射关系,存入到Set集合中
        Set<K> keySet = map.keySet();               获取键,将键存入Set集合中

|--Map

    |--Hashtable:底层是哈希表数据结构,不可以存入null键和null值。
                JDK1.0版本出现,效率低。该集合是线程同步的
    |--HashMap:底层是哈希表数据结构,允许使用null值和null键。将Hashable代替。
                  JDK1.2版本出现,效率高,该集合是不同步的
    |--TrreMap:底层是二叉树数据结构。可以用于给map集合中的键进行排序。线程不同步

Map和Set集合很像,其实,Set底层就是使用了Map集合

代码示例:

/*
  Map集合中的方法演示
*/
import java.util.*;
public class Demo {

    public static void main(String[] args) {
        Map<String,String> map = new HashMap<String,String>();

        //添加。如果添加时,出现相同的键。那么后添加的值会覆盖原有键对应的值。
        //并且put方法会返回被覆盖的值。
        print(map.put("01", "zhangsan1"));//结果:null
        print(map.put("01", "lisi"));//结果:zhangsan1。因为键相同,
                                    //后添加的值覆盖原有的值,put方法返回被覆盖的值
        map.put("02", "zhangsan2");
        map.put("03", "zhangsan3");
        map.put("04", "zhangsan4"); 
        map.put("05", null);// HashMap支持null键和null值
        print(map);//结果:{04=zhangsan4, 05=null, 01=lisi, 02=zhangsan2, 03=zhangsan3},输出结果是无序的,因为HashMap底层数据结构是哈希表

        //删除
        map.remove("02");
        print(map);//结果:{04=zhangsan4, 05=null, 01=lisi, 03=zhangsan3}

        //判断
        print(map.containsKey("03"));//结果:true。可以判断集合map中是否包含键03

        //获取
        print(map.get("02"));//结果:null。可以用get方法判断集合中是否包含元素,如果返回值为null,则不包含
        //print(map.get("03"));//结果:zhangsan3。可以用get方法判断集合中是否包含元素,如果返回值为null,则不包含

        Collection<String> coll = map.values();
        print(coll);//结果:[zhangsan4, null, lisi, zhangsan3]
    }
    public static void print(Object obj){
        System.out.println(obj);
    }
}

Map集合的第一种取出方式(KeySet方法)

代码示例:

/*
    keySet方法的使用

    Set<K> KeySet:将map中所有的键存入到Set集合。因为Set集合具备迭代器。
    所以可以用迭代器的方式取出所有的键,再根据get方法,获取每一个键对应的值

    Map集合取出原理:将Map集合转成Set集合,再通过迭代器取出。
*/
import java.util.*;
public class Demo {

    public static void main(String[] args) {
        Map<String,String> map = new HashMap<String,String>();
        map.put("01", "zhangsan1");
        map.put("02", "zhangsan2");
        map.put("03", "zhangsan3");
        map.put("04", "zhangsan4");

        Set<String> keySet =  map.keySet();//先获取map集合中所有键的Set集合

        Iterator<String> it = keySet.iterator();//有了Set集合。就可以获取其迭代器
        while(it.hasNext()){
            String key = it.next();//迭代器中的类型属于String
            String value = map.get(key);//有了键,就可以通过Map集合的get方法获取其对应的值
            print("key:"+key+" value:"+value);

            /*
             结果:
                key:04 value:zhangsan4
                key:01 value:zhangsan1
                key:02 value:zhangsan2
                key:03 value:zhangsan3
             */
        }
    }
    public static void print(Object obj){
        System.out.println(obj);
    }
}

Map集合的第二种取出方式(entrySet方法)

代码示例:

/*
    entrySet方法的使用

    Set<Map.Entry<K,V> entrySet: 将map集合中的映射关系存入到集合中,
    而这个关系的数据类型就是:Map.Entry
*/
import java.util.*;
public class Demo {

    public static void main(String[] args) {
        Map<String,String> map = new HashMap<String, String>();
        map.put("01", "zs1");
        map.put("02", "zs2");
        map.put("03", "zs3");
        map.put("04", "zs4");

        //将Map集合中的映射关系取出,存入到Set集合中
        Set<Map.Entry<String, String>> entrySet = map.entrySet();

        //有了Set集合。就可以获取其迭代器
        Iterator<Map.Entry<String, String>> it = entrySet.iterator();

        while(it.hasNext()){
            Map.Entry<String, String> me = it.next();//迭代器中的类型属于Map.Entry<String, String>
            String key = me.getKey();//Map.Entry<String, String>中的key类型属于String
            String value = me.getValue();//Map.Entry<String, String>中的key类型属于String
            print(key+".."+value);
        }
    }
    public static void print(Object obj){
        System.out.println(obj);
    }
}

Map集合的练习

/*
 * 每一个学生都有对应的归属地。
 * 学生Student,地址String.
 * 学生属性:姓名,年龄。
 * 注意:姓名和年龄相同视为同一个学生。
 * 保证学生的唯一性。
 * 
 * 1,描述学生。
 * 2,定义map容器。将学生作为键,地址作为值。存入。
 * 3,获取map集合中的元素。
 */
import java.util.*;

class Student implements Comparable<Student>{
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public int hashCode() {//覆盖hashCode方法,为了保证唯一性
        return name.hashCode() + age*15;
    }

    public boolean equals(Object obj) {//覆盖equals方法,为了保证唯一性
        if (!(obj instanceof Student))
            throw new ClassCastException("类型不匹配");
        Student stu = (Student) obj;
        return this.name.equals(stu.getName()) && this.age==stu.getAge();
    }

    public int compareTo(Student s) {//实现compareTo方法,使数据按照姓名排序
        int num = this.name.compareTo(s.getName());
        if(num == 0){
            return new Integer(this.age).compareTo(new Integer(s.getAge()));
        }
        return num;
    }

}

public class Demo {
    public static void main(String[] args) {
        HashMap<Student, String> hs = new HashMap<Student, String>();
        hs.put(new Student("zhangsan", 20), "北京");
        hs.put(new Student("zhangsan", 20), "北京");
        hs.put(new Student("lisi", 25), "北京");
        hs.put(new Student("wangwu", 30), "天津");
        //第一种获取方式
        Set<Student> keySet = hs.keySet();//先获取map集合中所有键的Set集合
        Iterator<Student> it = keySet.iterator();//有了Set集合。就可以获取其迭代器
        while(it.hasNext()){
            Student key = it.next();//获取键
            String value = hs.get(key);//获取键的值
            print("name=" + key.getName() + "...age=" + key.getAge() + "...地址="+ value);
            /*
             结果:
             name=lisi...age=25...地址=北京
            name=zhangsan...age=20...地址=北京
            name=wangwu...age=30...地址=天津
             */

        }

        //第二种获取方式
        Set<Map.Entry<Student, String>> entrySet = hs.entrySet();//将Map集合中的映射关系取出,存入到Set集合中
        Iterator<Map.Entry<Student, String>> it1 = entrySet.iterator();//有了Set集合。就可以获取其迭代器
        while (it1.hasNext()) {
            Map.Entry<Student, String> me = it1.next();//迭代器中的类型属于Map.Entry<String, String>
            Student stu = me.getKey();//获取键
            String s = me.getValue();//获取值
            print("name=" + stu.getName() + "........age=" + stu.getAge() + "........地址="+ s);
            /*
              结果: 
                name=lisi........age=25........地址=北京
                name=zhangsan........age=20........地址=北京
                name=wangwu........age=30........地址=天津
             */
        }
    }

    public static void print(Object obj) {
        System.out.println(obj);
    }
}
/*
 * 每一个学生都有对应的归属地。
 * 学生Student,地址String.
 * 学生属性:姓名,年龄。
 * 注意:姓名和年龄相同视为同一个学生。
 * 保证学生的唯一性。
 * 
 * 
 * 需求:对学生对象的 年龄 进行升序排序。
 * 
 * 因为数据是以键值对形式存在的。
 * 所以要使用可以排序的Map集合。TreeMap
 */
import java.util.*;
class Student implements Comparable<Student>{
    private String name;
    private int age;
    public Student(String name,int age){
        this.name = name;
        this.age = age;
    }
    public String getName(){
        return name;
    }
    public int getAge(){
        return age;
    }
    public int hashCode(){//覆盖hashCode方法,为了保证唯一性
        return name.hashCode() + age*18;
    }
    public boolean equals(Object obj){//覆盖equals方法,为了保证唯一性
        if(!(obj instanceof Student))
            throw new ClassCastException("类型转换异常");
        Student stu = (Student)obj;
        return this.name.equals(stu.getName()) && this.age == stu.getAge();
    }
    public int compareTo(Student stu){//实现compareTo方法,使数据按照姓名排序
        int num = name.compareTo(stu.getName());
        if(num == 0)
            return new Integer(age).compareTo(new Integer(stu.getAge()));
        return num;
    }
}

//定义一个比较器,使学生按照年龄排序
class StuAgeComparator implements Comparator<Student>{
    public int compare(Student s1,Student s2){
        int num = new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
        if(num == 0)
            return s1.getName().compareTo(s2.getName());
        return num;
    }
}
public class Demo {
    public static void main(String[] args) {
        TreeMap<Student, String> tm = new TreeMap<Student,String>(new StuAgeComparator());
        tm.put(new Student("zhangsan", 20), "天津");
        tm.put(new Student("zhangsan", 20), "北京");
        tm.put(new Student("lisi", 25), "北京");
        tm.put(new Student("wangwu", 30), "天津");

        Set<Map.Entry<Student, String>> entrySet = tm.entrySet();
        Iterator<Map.Entry<Student, String>> it = entrySet.iterator();
        while(it.hasNext()){
            Map.Entry<Student, String> me = it.next();
            Student stu = me.getKey();
            String s = me.getValue();
            print("name:"+stu.getName()+"...age:"+stu.getAge()+"...name:"+s);
            /*
             结果:
                name:zhangsan...age:20...name:北京
                name:lisi...age:25...name:北京
                name:wangwu...age:30...name:天津
             */
        }
    }

    public static void print(Object obj) {
        System.out.println(obj);
    }
}
/*
 * 练习:
 * "abcdeabcab"获取字符串中的字符出现次数。
 * 
 * 希望打印结果:a(3)b(3)c(2)....
 * 
 * 通过结果发现,每一个字母都有对应的次数,
 * 说明字符和次数之间都有映射关系。
 * 
 * 注意:当发现有映射关系时,可以选择Map集合。因为Map集合中存放的就是映射关系。
 * 
 * 说明时候使用Map集合呢?
 * 当数据之间存在映射关系时,就要现象Map集合。
 * 
 * 思路:
 * 1,将字符串转换成字符数组。因为要对每一个字母进行操作。
 * 2,定义一个Map集合,因为打印结果有序,所以使用TreeMap集合。
 * 3,遍历字符数组。
 *      将每一个字母作为键去查Map集合。
 *      如果返回null,将该字母和1存入到Map集合中。
 *      如果返回不为null,说明该字符在集合中已经存在,并有对应的次数。
 *      那么就获取该次数并进行自增,然后将该字母和自增后的次数存入到Map集合中,并覆盖掉原来键所对应的值   。
 * 4,将Map集合中的数据变成指定的字符串返回。
 */
import java.util.*;
public class Demo {
    public static void main(String[] args) {
        String s = charCount("abcdeabcab");
        System.out.println(s);//结果:a(3)b(3)c(2)d(1)e(1)
    }

    public static String charCount(String s) {
        StringBuilder sb = new StringBuilder();
        char[] chs = s.toCharArray();
        TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();//创建一个TreeMap集合
        for(int i=0;i<chs.length;i++){
            Integer value = tm.get(chs[i]);//获取键值
            if(value == null){
                tm.put(chs[i], 1);
            }
            else{
                value = value+1;
                tm.put(chs[i], value);
            }
        }
        Set<Map.Entry<Character,Integer>> entrySet = tm.entrySet();//将TreeMap的映射存入到Set集合中
        Iterator<Map.Entry<Character,Integer>> it = entrySet.iterator();//有了Set集合。就可以获取其迭代器
        while(it.hasNext()){
            Map.Entry<Character,Integer> me = it.next();//迭代器中的类型属于Map.Entry<String, String>
            sb.append(me.getKey()+"("+me.getValue()+")");
        }
        return sb.toString();
    }
}

Map集合的扩展知识

/*
 * Map扩展知识。
 * 
 * Map集合被使用时因为具备映射关系。
 * 
 * "yureban" "01" "zhangsan";
 * "yuerban" "02" "lisi";
 * "jiuyeban" "01" "wangwu";
 * "jiuyeban" "02" "zhaoliu";
 * 
 * 一个学校有 名字和多个教室,每个教室都有 学号和学生。
 * 如:一个学校名字为czbk,并且有yureban和jiuyeban。yureban中有
 * 多个学号和姓  名。jiuyeban中有 多个学号和姓名
 */
import java.util.*;
public class Demo {
    public static void main(String[] args) {
        //创建一个学校,学校中可以存放   教室名和教室中的内容
        HashMap<String, HashMap<String, String>> czbk = new HashMap<String, HashMap<String,String>>();
        //创建预热班教室,教室中可以存放   学号和姓名
        HashMap<String,String> yure = new HashMap<String, String>();
        //创建就业班教室,教室中可以存放   学号和姓名
        HashMap<String,String> jiuye = new HashMap<String, String>();

        czbk.put("yureban", yure);
        czbk.put("jiuyeban", jiuye);

        yure.put("01", "zhangsan");
        yure.put("02", "lisi");

        jiuye.put("01", "wangwu");
        jiuye.put("02", "zhaoliu");

        //遍历czbk集合。获取所有教室
        Iterator<String> it = czbk.keySet().iterator();
        while(it.hasNext()){
            String key = it.next();
            HashMap<String, String> value = czbk.get(key);
            print(key);
            printHashMap(value);
        }
    }
    public static void printHashMap(HashMap<String, String> hm){
        Set<Map.Entry<String, String>> entrySet = hm.entrySet();
        Iterator<Map.Entry<String, String>> it = entrySet.iterator();
        while(it.hasNext()){
            Map.Entry<String, String> me = it.next();
            String key = me.getKey();
            String value = me.getValue();
            print("xuehao:"+key+"....name:"+value);
            /*
             结果:
                jiuyeban
                xuehao:01....name:wangwu
                xuehao:02....name:zhaoliu
                yureban
                xuehao:01....name:zhangsan
                xuehao:02....name:lisi
             */
        }
    }
    public static void print(Object obj){
        System.out.println(obj);
    }
}
/*
 * Map扩展知识。
 * 
 * Map集合被使用时因为具备映射关系。
 * 
 * "yureban" Student("01" "zhangsan");
 * "yuerban" Student("02" "lisi");
 * "jiuyeban" Student("01" "wangwu");
 * "jiuyeban" Student("02" "zhaoliu");
 * 
 * 一个学校有多个教室,每个教室都有学号和姓名,把每个教室中的学号和姓名封装成对象。
 * 这种映射关系使用HashMap<String, ArrayList<Student>>
 * 在开发中这种用法比较常见
 */
import java.util.*;
import java.util.Map.Entry;
class Student{
    String name;
    int age;
    public Student(String name,int age){
        this.name = name;
        this.age = age;
    }
    public String getName(){
        return name;
    }
    public int getAge(){
        return age;
    }
    public String toString(){
        return name + "....." + age;
    }
}
public class Demo {
    public static void main(String[] args) {
        //创建一个学校,学校中可以存放   教室名和学生对象。
        HashMap<String, List<Student>> czbk = new HashMap<String, List<Student>>();

        //创建一个 预热班 的学生集合
        ArrayList<Student> yure = new ArrayList<Student>();

        //创建一个 就业班 的学生集合
        ArrayList<Student> jiuye = new ArrayList<Student>();

        //将 预热班 学生的集合添加到 预热班 中
        czbk.put("yureban", yure);

        //将 就业班 学生的集合添加到 就业班 中
        czbk.put("jiuyeban", jiuye);

        yure.add(new Student("zhangsan01",20));//在预热班中添加一个学生对象
        yure.add(new Student("zhangsan02",30));//在预热班中添加一个学生对象

        jiuye.add(new Student("lisi01",20));//在就业班中添加一个学生对象
        jiuye.add(new Student("lisi02",30));//在就业班中添加一个学生对象

        Iterator<Map.Entry<String, List<Student>>> it = czbk.entrySet().iterator();
        while(it.hasNext()){
            Map.Entry<String, List<Student>> me = it.next();
            String key = me.getKey();
            List<Student> value = me.getValue();
            print(key);
            printArrayList(value);
            /*
             结果:
                jiuyeban
                lisi01.....20
                lisi02.....30
                yureban
                zhangsan01.....20
                zhangsan02.....30
             */
        }
    }
    public static void printArrayList(List<Student> al){
        Iterator<Student> it = al.iterator();
        while(it.hasNext()){
            Student stu = it.next();
            print(stu);     //相当于print(stu.toString());
        }
    }
    public static void print(Object obj){
        System.out.println(obj);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值