java从0的二倍速学习系列——泛型,Collections工具类,Arrays工具类

1. 一个集合的问题

同时存在

list.add("str1")
list.add(123)

的情况下,无法很好的分辨存储的数据类型,导致后序List调用出错。
因为collection默认存储Object类型数据,所以编译过程中不会报错。
所以我们希望在创建集合时,就明确类型。
List<String> li = new ArratyList<String>()

  1. 保证安全
  2. 将运行时ClassCastException转移到了编译时期检查

2. 集合泛型的使用


注意
Iterator<String> it = XXX.iterator();
Comparator<String>

3. 泛型的擦除

在编译后,会进行泛型的擦除,在生成.class文件后,泛型消失
泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”。

3. 泛型类的使用

和模板类一样

class Example<E,Q,W>{	//设置泛型
    private E para1;
    private Q para2;
    private W para3;

    public Example(E para1, Q para2, W para3) {
        this.para1 = para1;
        this.para2 = para2;
        this.para3 = para3;
    }
    public void show(){
        System.out.println("para1 = "+para1);
        System.out.println("para2 = "+para2);
        System.out.println("para3 = "+para3);
    }
}
public class demo {

    public static void main(String[] args) {
        Example<String,Integer,Float> ex = new Example<String, Integer, Float>("str",12,78F);//根据泛型进行初始化
        ex.show();
    }
结果
para1 = str
para2 = 12
para3 = 78.0

3.1 泛型类的泛型方法

类内的方法,也可以使用泛型

public <G> void  show2(G g){
        System.out.println("G= "+g);
    }
    ------------------------------
      ex.show2("string");
        ex.show2(1234f);
        ex.show2(new Exception("213"));
结果
G= string
G= 1234.0
G= java.lang.Exception: 213

3.2 泛型中的静态方法

  1. 静态方法,无法使用类的泛型,但是可以定义为泛型方法。
  2. 如果方法是静态的,还需要使用泛型,那么泛型必须定义在方法上

3.3 泛型的接口

如果子类能明确类型,接口可以直接定义类型
如果不明确,可以类对象初始化时明确类型。

interface Inter<E>{
	void show(E e);
}

class InterImpl implements Inter<String>{
	void show(String e){.....}
}

class InterImpl2<T> implements Inter<T>{
	public void show(T e){....}
}

3.4 泛型通配符

当传入的泛型类型不明时,可以采用通配符进行控制。
如下代码:分别由String的HashSet与Integer的ArrayList组成,通过将打印函数的参数设置为其父类,并且使用通配符,能够完成参数的传入Collection<?> colle

public class demo {
    public static void printCollection(Collection<?> colle){
    //使用父类与类型通配符进行传参
        for (Iterator it = colle.iterator();it.hasNext();){
        	//因为类型不明,可能为Integer或者String,所以直接打印toString
            System.out.println(it.next().toString());
        }
    }
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        list.add(135);
        list.add(246);
        list.add(680);
        printCollection(list);

        Set<String> se = new HashSet<String>();
        se.add("123");
        se.add("456");
        se.add("789");
        printCollection(se);
    }
运行结果
135
246
680

123
456
789

通配符也可以用来代替泛型方法

    //使用通配符
    public static void test(List<?> list) { }
    //使用泛型方法
    public <T> void  test2(List<T> t) { }

3.5 泛型限定:相比通配符的全部类型加了些限制类型,上限与下限

如果想要限制一些类型,不是通配符的全部类型,需要使用泛型的限定。
? extends E //E类的子类对象或E类对象,上限
? super E //接受E的父类对象或E类对象,下限

 public static void printCollection(Collection<? extends Object> 
 colle)
 //此处限定的意思是,Object的子类,所有对象,此处只做例子。
 {
        for (Iterator<? extends Object> it = colle.iterator();it.hasNext();){
        	Object obj = it.next();
            System.out.println(obj);
        }
    }

3.6 泛型的一个例子,使用泛型强化泛用性

如下图可见,该方法具有局限性,只能完成对于student对象的集合的最大值的获取。
但是也无法定义为默认的Object,因为Object没有compareTo,无法比较大小

public static student getMax(Collection<student> co){
		// xxxxx   code   xxxxx  
        return  null;
    }
    public static void main(String[] args) {
        List<student> list = new ArrayList<student>();
        list.add(new student(11,"zhang1"));
        list.add(new student(13,"zhang2"));
        list.add(new student(19,"zhang3"));
        student maxStu = getMax(list);
        }

如果使用Object,没有限定存入内容,鲁棒性不强。

public static Object getMax(Collection co){
        Iterator it = co.iterator();
        Object max =it.next();
        while (it.hasNext()){
            Object o = it.next();
            Comparable tmp = (Comparable)o;
            //接口的多态,实现接口的类也是子类
            //Object类没有CompareTo方法,需要强转
            if(tmp.compareTo(max)>0){max = tmp;}
        }
        return  max;
 public static void main(String[] args) {
 	Collection<student> list = new ArrayList<student>();
        list.add(new student(11,"zhang1"));
        list.add(new student(13,"zhang2"));
        list.add(new student(19,"zhang3"));
        student maxStu = (student) getMax(list);
        }

通过泛型方法限定,增强鲁棒性。
如下方法中:

  1. 传入为T或T的子类构成的集合Collection<? extends T>
  2. 同时,限定T必须为Comparable的子类T extends Comparable
  3. 同时,限定Comparable中的compareTo方法,必须被T或T的父类实现Comparable<? super T>
 public  static <T extends Comparable<? super T>> T getMax(Collection<? extends T> co){
        Iterator<? extends T> it = co.iterator();
        T max =it.next();
        while (it.hasNext()){
            T tmp = it.next();
            if(tmp.compareTo(max)>0){max = tmp;}
            //此处存在限定,T必须为Comparable的子类,
            // 同时,Comparable必须在T或T的父类,实现comparaTo方法
        }
        return  max;
    }

4. Collections工具类

如上面3.6小节所述:可以定义Collection工具类来集成一些集合共有的方法。

4.1 排序相关操作

Collections提供以下方法对List进行排序操作

  1. void reverse(List list):反转

  2. void shuffle(List list),随机排序

  3. void sort(List list),按自然排序的升序排序

  4. void sort(List list, Comparator c);定制排序,由Comparator控制排序逻辑

  5. void swap(List list, int i , int j),交换两个索引位置的元素

  6. void rotate(List list, int distance),旋转。
    当distance为正数时,将list后distance个元素整体移到前面。当distance为负数时,将 list的前distance个元素整体移到后面。

package collection;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class CollectionsTest {
    public static void main(String[] args) {
        ArrayList nums =  new ArrayList();
        nums.add(8);
        nums.add(-3);
        nums.add(2);
        nums.add(9);
        nums.add(-2);
        System.out.println(nums);
        Collections.reverse(nums);
        System.out.println(nums);
        Collections.sort(nums);
        System.out.println(nums);
        Collections.shuffle(nums);
        System.out.println(nums);
        //下面只是为了演示定制排序的用法,将int类型转成string进行比较
        Collections.sort(nums, new Comparator() {
			//临时创建Comparator内部类对象
            @Override
            public int compare(Object o1, Object o2) {
                // TODO Auto-generated method stub
                String s1 = String.valueOf(o1);
                String s2 = String.valueOf(o2);
                return s1.compareTo(s2);
            }

        });
        System.out.println(nums);
    }
}
运行结果
[8, -3, 2, 9, -2]
[-2, 9, 2, -3, 8]
[-3, -2, 2, 8, 9]
[9, -2, 8, 2, -3]
[-2, -3, 2, 8, 9]

4.2 查找替换相关操作

  1. int binarySearch(List list, Object key), 对List进行二分查找,返回索引,注意List必须是有序的

  2. int max(Collection coll),根据元素的自然顺序,返回最大的元素。 类比int min(Collection coll)

  3. int max(Collection coll, Comparator c),根据定制排序,返回最大元素,排序规则由Comparatator类控制。类比int min(Collection coll, Comparator c)

  4. void fill(List list, Object obj),用元素obj填充list中所有元素

  5. int frequency(Collection c, Object o),统计元素出现次数

  6. int indexOfSubList(List list, List target), 统计targe在list中第一次出现的索引,找不到则返回-1,类比int lastIndexOfSubList(List source, list target).

  7. boolean replaceAll(List list, Object oldVal, Object newVal), 用新元素替换旧元素。

package collection.collections;

import java.util.ArrayList;
import java.util.Collections;

public class CollectionsTest {
    public static void main(String[] args) {
        ArrayList num =  new ArrayList();
        num.add(3);
        num.add(-1);
        num.add(-5);
        num.add(10);
        System.out.println(num);
        System.out.println(Collections.max(num));
        System.out.println(Collections.min(num));
        Collections.replaceAll(num, -1, -7);
        System.out.println(Collections.frequency(num, 3));
        Collections.sort(num);
        System.out.println(Collections.binarySearch(num, -5));
    }
}
运行结果
[3, -1, -5, 10]
10
-5
 1
1

4.3 同步控制相关(待补)

5. Arrays工具类

用于操作数组的工具类,不是collection集合
类中定义静态工作方法

  1. 排序
  2. 二分查找
  3. 数组复制
  4. 判断两个数的内部元素,判断是否相同
  5. 将数组转化为字符串
  6. 将数组转为列表
    详见文档,略

5.1 Arrays的特点

  1. Arrays操作的数组,Collections操作的是List.

  2. 在sort()和binarySearch()中Collections要求加一个Comparator对象;

  3. Collections可以用shuffle()对List对象进行乱序;

  4. Arrays有 asList() 可以将数组或可变参数转换为List对象,Collection对象则可以直接用 ToArray(T[] a) 集合转化为数组

    String[] str = {"13","213","31"};
    List<String> list = Arrays.asList(str);
    //通过转为集合,能够便于操作集合中的元素
    下面错误行为
    list.add("new"); //UnsupportedOperationException
    

    重点:转换为list后,列表长度固定,不可CURD(增删改查)

    List<String> list = new ArrayList<String>();
    list.add("123");
    list.add("333");
    list.add("544");
    String[] str_arr = c.ToArray(new String[c.size()]);
    
  5. 如果数组存储基本数据类型(Integer),转成集合,数组对象存入集合(集合里面为数组胡地址)

  6. 如果数组存储引用数据类型(String),转成集合,数组元素存入集合。

int[] arr = {123,412,14};
List list = Arrays.asList(arr); //此时存入的是数组对象的地址(@XXXX)
List<int[]> list = Arrays.asList(arr);//正确操作,三个数组元素存入列表。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值