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

——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{//定义泛型类
    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  void print(W w){//泛型类中也可以定义泛型方法。

    }
    public static  void speak(){//静态方法不可以访问类上定义的泛型,因为类上的泛型必须要通过创建对象后才能实现,而静态加载出现在对象之前。
        //另外注意泛型放在返回值类型前面。

    }
}
class FanXinDemo{
    public  void show(T t){//为了避免泛型类的以上弊端,我们可以定义泛型方法。
        System.out.println("show");
    }
    public  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 ts = new TreeSet(new MyLock());
        ts.add(new Student("java01"));
        ts.add(new Student("java08"));
        ts.add(new Student("java00"));
        ts.add(new Student("java05"));

        TreeSet ts1 = new TreeSet(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 it = ts.iterator();it.hasNext();){
//          System.out.println(it.next().getName());
//      }
//      for(Iterator it = ts1.iterator();it.hasNext();){//书写很麻烦
//          System.out.println(it.next().getName());
//      }
        print(ts);
        print(ts1);//定义一个打印方法
    }
    public static void print(TreeSet ts){//利用泛型限定简化了书写,利于程序后期扩展。
        for(Iterator 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{//
    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 list = new ArrayList();
        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()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 list = new ArrayList();
        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 myFill(List list,int start,int end){

        List 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 ts = new TreeSet(Collections.reverseOrder(new StrLenthCom()));//强行逆转比较器,可以实现自然排序的反转,也可以实现自定义比较器的反转。
        //这种功能一定要记住~
        ts.add("aaaa");
        ts.add("bb");
        ts.add("c");
        ts.add("dxaio");
        for (Iterator it = ts.iterator(); it.hasNext();){
            System.out.println(it.next());
        }
    }

}
/*之前定义过的比较器,拿来演示
class StrLenthCom implements Comparator{
    public int compare(String s1,String s2){
        if(s1.length()>s2.length())
            return 1;
        if(s1.length()

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 list = new ArrayList();
        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 tm = new TreeMap();
        tm.put(1, "java01");
        tm.put(2, "java02");
        tm.put(3, "java03");
        tm.put(4, "java04");
        //KaySet方式的高级for循环
        Set s = tm.keySet();
        for(Integer i : s){
            System.out.println(i+":"+tm.get(i));
        }
        //entrySet方式的高级for循环
        for(Map.Entry 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强行逆转比较器方法,这些内容方法都是非常实用的方法,掌握它们有时候会让代码精简很多。所以任何的知识点都要引起重视,一次记不住争取第二次就能记住。

你可能感兴趣的:(JAVA基础学习笔记)