黑马程序员——Java基础---泛型、集合框架工具类:Collections和Arrays、JDK 1.5新特性

来源:互联网 发布:淘宝森系口碑好的店铺 编辑:程序博客网 时间:2024/05/21 07:11

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

第一部分 泛型
泛型:广泛的类型。就是给对象指定数据类型的安全机制。泛型是JDK1.5 版本以后出现的新特性。用于解决数据的安全问题。是一个安全机制。

好处:

1、将运行时期出现问题 ClassCastException,转移到了编译时期。防便于程序员解决问题。让运行时问题减少,提高安全。

2、避免了强制转换的麻烦。

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

泛型又可以细分为:

1、泛型集合

2、泛型类

3、泛型接口

4、高级泛型

一、泛型集合

在使用java提供的对象时,什么时候写泛型呢?通常在集合框架中很常见。只要见到<>就是定义泛型。其实<>就是用来接收数据类型的。当使用集合时,将集合中要存储的数据类型作为参数传递到<>尖括号中即可。

1)Demo:

    ArrayList<String> al = new ArrayList<String>();//加了“ <> ”。就表示泛型结构,为了定义容器的数据类型,减少出错。         al.add("java01");        al.add("java02");        al.add("java04");        al.add(2,"java03");        ListIterator<String> li = al.listIterator();        //指定迭代器的数据类型          while (li.hasNext()){            String str = li.next();//这时候就不需要强转了,避免了强制转换的麻烦            if(obj.equals("java02")){//              li.set("java002");//修改操作//              li.remove();//删除操作            }            System.out.println(str);//        }

二、泛型类,泛型方法和泛型接口

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

2) 泛型类定义的泛型在整个类中有效。如果被方法使用,那么泛型类的对象要明确操作的具体类型后,所有要操作的类型就已经固定了。为了让不同方法可以操作不同类型,而且类型还不确定,那么可以将泛型定义在方法上。

3) 特殊之处:

静态不可以访问类上定义的泛型。

如果静态方法操作的引用数据类型不确定,可以将泛型定义在方法中。

4) 定义泛型类:

1、可以定义泛型类:class DemoGe< T>

2、可以定义泛型方法:public < S> void show(S s)

3、可以同时定义泛型类和泛型方法。

5) Demo :

package fuxi1;/** *  *@author XiaLei */public class Day15Test3 {    public static void main(String[] args) {    }}class FanXin<T>{//定义泛型类    public void show(T t){        System.out.println("show");    }    public void run(T t){        System.out.println("run");    }    /*     * 如果不定义泛型类,那么就需要在每一个方法后面传入具体参数,较为麻烦。例如     * public void show(String s){}     * public void run(String s){}     * 简化书写的同时,也出现了弊端,即泛型类一旦明确了类型,则所有的方法都要使用该类型。     */    public <W> void print(W w){//泛型类中也可以定义泛型方法。    }    public static <W> void speak(){//静态方法不可以访问类上定义的泛型,因为类上的泛型必须要通过创建对象后才能实现,而静态加载出现在对象之前。        //另外注意泛型放在返回值类型前面。    }}class FanXinDemo{    public <T> void show(T t){//为了避免泛型类的以上弊端,我们可以定义泛型方法。        System.out.println("show");    }    public <T> void run(T t){        System.out.println("run");    }}

三、高级泛型
当传入的类型不确定时,可以使用通配符?。也可以理解为占位符。使用通配符的好处是可以不用明确传入的类型,这样在使用泛型类或者泛型方法时,提高了扩展性。

Demo:

package fuxi1;import java.util.Comparator;import java.util.Iterator;import java.util.TreeSet;/** * 泛型限定:用于泛型拓展。 * ? 通配符,也可以理解为占位符。 * ?extends E:可以接受E或者E的子类。上限。 * ?super E:可以接受E或者E的父类。下限。 *@author XiaLei */public class Day15Test4 {    public static void main(String[] args) {        TreeSet<Student> ts = new TreeSet<Student>(new MyLock());        ts.add(new Student("java01"));        ts.add(new Student("java08"));        ts.add(new Student("java00"));        ts.add(new Student("java05"));        TreeSet<GoodStudent> ts1 = new TreeSet<GoodStudent>(new MyLock());        ts1.add(new GoodStudent("java--01"));        ts1.add(new GoodStudent("java--08"));        ts1.add(new GoodStudent("java--00"));        ts1.add(new GoodStudent("java--05"));//      for(Iterator<Student> it = ts.iterator();it.hasNext();){//          System.out.println(it.next().getName());//      }//      for(Iterator<GoodStudent> it = ts1.iterator();it.hasNext();){//书写很麻烦//          System.out.println(it.next().getName());//      }        print(ts);        print(ts1);//定义一个打印方法    }    public static void print(TreeSet<? extends Student> ts){//利用泛型限定简化了书写,利于程序后期扩展。        for(Iterator<? extends Student> it = ts.iterator();it.hasNext();){            System.out.println(it.next().getName());        }    }}class Student{    String name;    public Student(String name) {        super();        this.name = name;    }    public String getName(){        return name;    }}class GoodStudent extends Student{    public GoodStudent(String name) {        super(name);    }    public String getName(){        return name;    }}class MyLock implements Comparator<Student>{//<? super >    public int compare(Student s1,Student s2){        return s1.getName().compareTo(s2.getName());    }}

第二部分 Collections和Arrays

一、Collections

1)常用方法:

1、sort 方法:给 list 集合排序,用 sort 方法。

2、max 方法:取 list 集合中的最大值。用 max 方法。

demo:

package fuxi1;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.List;/** * 集合框架工具类 * 需求:利用Collections工具类给List集合排序,以及求最大值等等。 * 思路:Collections的sort方法就是专门给List集合排序的,如果需要指定比较方法可以创建比较器。 * max方法则是给出最大值,同样也可以加比较器。 *@author XiaLei */public class Day17Test1 {    public static void main(String[] args) {        List<String> list = new ArrayList<String>();        list.add("fdsa");        list.add("fda");        list.add("s");        list.add("ss");        list.add("adfss");//      Collections.sort(list);//按照字符串自然顺序排序。//      System.out.println(list);        Collections.sort(list,new StrLenthCom());//创建比较器,按照字符串长度排序。        System.out.println(list);//      String max = Collections.max(list,new StrLenthCom());//创建比较器,按照字符串长度求最大值。//      System.out.println(max);        int index = Collections.binarySearch(list, "s",new StrLenthCom());//二分查找,如果元素不在则返回-(应插入位置角标)-1;        System.out.println(index);    }}class StrLenthCom implements Comparator<String>{    public int compare(String s1,String s2){        if(s1.length()>s2.length())            return 1;        if(s1.length()<s2.length())            return -1;        else            return s1.compareTo(s2);    }}

3、binarySearch:查询的字符串在集合中是否存在。返回 -1 ,表示不存在;返回 0 ,则存在。

4、fill :将list集合所有元素替换成指定元素。

fill练习:

package fuxi1;import java.util.ArrayList;import java.util.Collections;import java.util.List;/** * 需求:利用集合框架工具类的fill方法给集合中部分元素替换成指定元素。 * 思路:利用List集合subList方法,查询集合部分元素并替换。 *@author XiaLei */public class Day17Test2 {    public static void main(String[] args) {        List<String> list = new ArrayList<String>();        list.add("fdsa");        list.add("fda");        list.add("s");        list.add("ss");        list.add("adfss");//      Collections.fill(list, "hah");//      System.out.println(list);        myFill(list,1,2);//改变部分元素。        System.out.println(list);        Collections.replaceAll(list, "s", "x");//替换        System.out.println(list);        Collections.reverse(list);//反转        System.out.println(list);    }    public static List<String> myFill(List<String> list,int start,int end){        List<String> list1 =list.subList(start, end);        Collections.fill(list1, "haha");         return list;    }}

打印结果:
这里写图片描述

5、reverseOrder :强行逆转比较器。
demo:

package fuxi1;import java.util.Collections;import java.util.Iterator;import java.util.TreeSet;/** *  *@author XiaLei */public class Day17Test3 {    public static void main(String[] args) {        TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder(new StrLenthCom()));//强行逆转比较器,可以实现自然排序的反转,也可以实现自定义比较器的反转。        //这种功能一定要记住~        ts.add("aaaa");        ts.add("bb");        ts.add("c");        ts.add("dxaio");        for (Iterator<String> it = ts.iterator(); it.hasNext();){            System.out.println(it.next());        }    }}/*之前定义过的比较器,拿来演示class StrLenthCom implements Comparator<String>{    public int compare(String s1,String s2){        if(s1.length()>s2.length())            return 1;        if(s1.length()<s2.length())            return -1;        else            return s1.compareTo(s2);    }}*/

6、shuffle :随机排序。

7、swap :交换位置。
demo:

package fuxi1;import java.util.ArrayList;import java.util.Collections;import java.util.List;/** *  *@author XiaLei */public class Day17Test4 {    public static void main(String[] args) {        List<String> list = new ArrayList<String>();        list.add("fdsa");        list.add("fda");        list.add("s");        list.add("ss");        list.add("adfss");        Collections.swap(list, 1, 4);//换位。        System.out.println(list);        Collections.shuffle(list);//随机排序。        System.out.println(list);    }}

二、Arrays

Arrays是用于操作数组的工具类。
1)将数组转换为集合
注意:
a、将数组转换成集合,不可使用集合的增删方法,因为数组的长度是固定的。如果进行增删操作,则会产生UnsupportedOperationException的编译异常。
b、如果数组中的元素都是对象,则变成集合时,数组中的元素就直接转为集合中的元素。
c、如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。

好处:可以使用集合的思想和方法来操作数组中的元素。

2)集合变数组
指定类型的数组到底要定义多长呢?
当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组。长度为集合的size。
当指定类型的数组长度大于了集合的size,就不会新创建了数组。而是使用传递进来的数组。
所以创建一个刚刚好的数组最优。

好处: 可以限定对元素的操作,不可以进行增删了。

第三部分 JDK 1.5的新特性

一、静态导入

1、当类名重名时。需要指定具体的包名

2、当方法重名时。指定具备所属的对象或者类。

二、方法的可变参数

1) 使用注意:可变参数,一定要定义在参数列表的后面。

2) 可变参数传递的使用方式:其实就是上一种数组的参数简写形式,不用每次都动手的建立数组对象,只要将操作的元素作为参数传递即可,隐式的将这些参数封装成了数组。

3) 可变参数的写法:public static void show2(String s,int…arr){}

三、高级 for 循环

1)格式:

for(数据类型 变量名:被遍历的集合(collection) 或者数组){

}

2)for 对集合的遍历,只能获取元素,但是不能对集合进行操作。迭代器除了对集合进行遍历,还能进行 remove 集合中元素的动作。如果是用 ListIterator,还可以在遍历过程中对集合进行增删改查的动作。

3)高级 for 循环的局限性:高级 for 有一个局限性,必须有被遍历的目标。

4)建议:在遍历数组的时候,还是希望使用传统的 for ,因为传统 for 可以定义脚标。高级for:只能对集合中的数据取出,不能做到修改集合中的元素,即使是赋值也没办法。

Demo:

package fuxi1;import java.util.Map;import java.util.Set;import java.util.TreeMap;/** * 演示高级for循环。 * 反思:事实上在写博客的时候,我已经是在复习了。高级for也已经用过很多次了,然而在前面的复习中,尤其是集合框架这章, * 用了很多的迭代器进行打印,完全忘了用高级for循环,这就说明了之前学习的不认真,希望自己能够更加努力! *@author XiaLei */public class Day17Test5 {    public static void main(String[] args) {        TreeMap<Integer,String> tm = new TreeMap<Integer,String>();        tm.put(1, "java01");        tm.put(2, "java02");        tm.put(3, "java03");        tm.put(4, "java04");        //KaySet方式的高级for循环        Set<Integer> s = tm.keySet();        for(Integer i : s){            System.out.println(i+":"+tm.get(i));        }        //entrySet方式的高级for循环        for(Map.Entry<Integer,String> me : tm.entrySet()){            System.out.println(me.getKey()+"="+me.getValue());        }    }}

四、JDK 1.5 自动装箱与拆箱

1)Integer i = 5;//自动装箱new Integer(5);

2)i = i+2; //i进行自动拆箱,变成了 int 类型,再和 2 相加,再进行装箱赋值给 i 。

3)byte范围是-128~127之间,所以Integer m,n = 128;已经超出byte范围,所以虽然看似相同,其实他们指向了两个不同的 Integer 对象。

总结
本章知识比较零碎,很多内容容易忽视,比如Collections里的reverseOrder强行逆转比较器方法,这些内容方法都是非常实用的方法,掌握它们有时候会让代码精简很多。所以任何的知识点都要引起重视,一次记不住争取第二次就能记住。

0 0
原创粉丝点击