day15 API04-1集合--泛型、Collection接口、List接口、ArrayList、LinkedList

1.泛型

为什么引入泛型?

1)泛型是为了模拟数组的元素类型检查

2)泛型通常与集合一起使用,用来约束集合中元素的类型

3)泛型的格式:,这个Type必须是引用类型(包括包装类型),不能是基本类型

4)泛型可以帮助我们写出更加通用的代码,减少代码的冗余,提高程序通用性

5)写泛型一定要注意格式的要求(定义集合/定义泛型方法)

泛型集合:

泛型方法:

 

6)泛型是一个“语法糖”,可以提前报错,在编译前就可以检查数据的类型,如果不是要求的类型,就报错;但是通过编译以后,泛型的作用就消失了,也就是说,编译后生成的字节码文件中没有泛型

7)高效for循环

格式:

for(每轮遍历得到的元素的类型   遍历得到的元素名字 : 要遍历的元素){循环体}
与普通for循环使用哪一个都可以
优点:比普通for循环写法简单,效率高

缺点:没有办法按照下标来操作值,只能从头到尾依次遍历

8)泛型的声明:泛型可以在接口/类/方法上使用

9)泛型<?>常用方法

泛型常用名称

E

Element(在集合中使用,因为集合中存放的是元素)

T

Type(Java中的类)

K

Key(键)

V

Value(值)

N

Number(数值类型)

?

表示不确定的java类型

练习1:泛型集合的使用

package cn.tedu.generic;
import java.util.ArrayList;
import java.util.List;
/*本类测试泛型的优点1*/
public class TestGeneric1 {
    public static void main(String[] args) {
        /*1.泛型是怎么产生的?--想要模拟数组的类型检查*/
        //1.创建一个String类型的长度为5的数组
        String[] a =new String[5];
        //数组的好处:在编译时检查数据的类型,如果不是指定的类型就报错
//        a[0] = 1;
//        a[1] = 3.4;
//        a[2] = 'a';
        a[3] = "泡泡";
        a[4] = "超超";
        /*2.泛型通常结合着集合一起使用*/
        //多态对象:父类引用 指向子类对象
        List list = new ArrayList();//注意导包:java.util...
        //没有类型约束,数据类型太自由!!!无法进行运算或者其他行为
        list.add("平平");
        list.add(1);
        list.add(6.6);
        list.add('a');
        System.out.println(list);//[平平, 1, 6.6, a],查看集合中的元素结果

        /*3.引入泛型--主要目的是想通过泛型<?> 来约束集合中的数据类型
        4.泛型的好处:可以把报错的时机提前,在编译期就报错,而不是运行后才抛出异常
        向集合中添加元素时,会先检查元素的数据类型,不是要求的数据类型就编译失败*/
        List<String> list2 = new ArrayList<String>();//注意导包:java.util...
//        list2.add(1);
//        list2.add(6.6);
//        list2.add('a');
        list2.add("平平");
        System.out.println(list2);//[平平]

        /*5.<type> --type该如何写?
        * 可以根据自己的需求设定类型,但注意必须是引用类型(包装类型),不能是基本类型*/
        //List<int> list3 = new ArrayList<int>();//Type argument cannot be of primitive type
        List<Integer> list3 = new ArrayList<Integer>();
        for(int i =100;i<=500;i+=100){
           list3.add(i);
        }
        System.out.println(list3);//[100, 200, 300, 400, 500]
    }
}

练习2:泛型方法的使用

package cn.tedu.generic;

import java.util.Arrays;

/*本类测试泛型的优点2*/
public class TestGeneric2 {
    public static void main(String[] args) {
        //需求:打印指定数组中的所有元素
        Integer[] a = {123456789};
        String[] b ={"大哥","二哥","三哥","四哥","五哥","六哥","小弟"};
        Double[] c ={6.0,6.6,6.66,6.666,6.6666};
        print(a);
        print(b);
        print(c);
    }
    /*1.泛型可以实现通用代码的编写,使用E表示元素的类型是Element类型
    * 2.泛型的语法要求:如果在方法上使用泛型,必须两处同时出现
    * 一个是传入参数的类型是泛型,另一个是返回值前的泛型类型
    * 表示这是一个泛型方法*/
    private static<E> void print(E[] e) {
        for (E f: e){//E是泛型类型,f是随便起的名字,e是所有数组名的统称
            System.out.println(f);
        }
    }

//    private static void print(Double[] c) {
//        for (Double d : c){
//            System.out.println(d);
//        }
//
//    }
//
//    private static void print(String[] b) {
//        for (String s: b){
//            System.out.println(s);
//        }
//
//    }
//
//    private static void print(Integer[] a) {
//        //普通for循环遍历数组
//        /*普通for循环
//        * 优点:可以设置循环的步长(怎么变化)*/
        for(int i = 0;i<a.length;i++){
            System.out.println(a[i]);
        }
//        /*高效for循环(增强for循环)
//        * 格式:for(1 2 : 3){循环体}
//        * 1是每次遍历得到的元素类型,
//        * 2是遍历得到的元素的名字,
//        * 3是要遍历的元素
//        * 优点:比普通for循环写法简单,效率高
//        * 缺点:没有办法按照下标来操作值,只能从头到尾依次遍历*/
//        for (Integer i: a){
//            System.out.println(i);
//        }
//    }
}

2.集合Collection接口

2.1集合和数组区别:

都是容器:

1)数组array:长度是固定的,通过数组下标访问内容,访问方式比较单一,插入/删除等操作较繁琐

2)集合collection:长度可变,访问方式比较灵活

3)java常用集合关系

2.2集合Collection

1)存放对象的数据结构,而且长度可变,可以存放不同类型的对象,并且还提供了一组操作成批对象的方法.
2)Collection接口层次结构中的根接口,接口不能直接使用,但是该接口提供了添加元素/删除元素/管理元素的父接口公共方法.
3)由于List接口与Set接口都继承了Collection接口,因此这些方法对于List集合和Set集合是通用的.

2.3Collection方法速查表

2.3.1针对单个集合的常用方法

针对单个集合的常用方法

c.add(100)

向集合c添加元素100

clear()

清空集合中所有的元素

contains()

判断集合是否包含指定元素

hashCode()

获取集合的哈希码值

isEmpty()

判断集合是否为空

remove()

移除指定元素(首次出现),成功返回true

size()

获取集合个数

equals()

比较两对象是否相等

Object[] array = c.toArray();

集合转成数组,数组用Arrays.toString()查看

2.3.2针对两集合之间的常用方法

集合与集合之间的常用方法

c.addAll(c2)

把c2集合添加到c集合中(泛型上/下限)

c.containsAll(c2)

判断c集合是否包含c2集合中的所有元素

c.retainAll(c2)

取两集合之间的公共部分(交集)

c.removeAll(c2)

删除c集合中属于c2集合的所有元素

package cn.tedu.collection;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.Callable;

/*本类测试Collection相关API方法*/
public class TestCollection {
    public static void main(String[] args) {
        //1.创建Collection接口对象,因为Collection是接口,也是接口List,不能自身创建对象
        //Collection c =new Collection();
        //Collection<Integer> c = new List<Integer>();
        /*1.<Integer>是泛型,用来约束集合c中可存入的元素类型
        * 泛型中的<type>只能是引用类型,不能是基本类型*/
        //只能用List接口的子类创建对象
        Collection<Integer> c = new ArrayList<Integer>();

        //2.1测试常用方法--针对单个集合的方法
        c.add(100);//向集合中添加元素
        c.add(200);//add()添加
        c.add(300);
        c.add(400);
        c.add(500);
        System.out.println(c);//[100, 200, 300, 400, 500],打印查看集合中的元素

        //c.clear();//清空集合中的所有元素
        System.out.println(c);//[]

        System.out.println(c.contains(300));//true,判断集合是否包含指定元素300

        System.out.println(c.hashCode());//127240651,获取哈希码值

        System.out.println(c.isEmpty());//false,判断集合是否为空

        System.out.println(c.remove(300));//true,移除指定元素,成功返回true
        System.out.println(c);//[100, 200, 400, 500]

        System.out.println(c.size());//4,获取集合的个数

        System.out.println(c.equals(200));//false,比较两个对象是否相等

        //Alt+Enter,自动补全正确的类型
        Object[] array = c.toArray();//集合对象转成数组,数组用Arrays.toString()查看
        System.out.println(Arrays.toString(array));//[100, 200, 400, 500]

        //2.2集合与集合之间的操作
        Collection<Integer> c2 = new ArrayList<>();//创建第二个集合对象c2

        c2.add(2);//
        c2.add(4);//
        c2.add(6);//向集合中添加指定元素
        System.out.println(c2);//[2, 4, 6],打印查看c2集合中的元素

        c.addAll(c2);//把c2集合添加到c集合中
        System.out.println(c);//[100, 200, 400, 500, 2, 4, 6]

        System.out.println(c.contains(c2));//false,c集合是否包含指定元素c2
        System.out.println(c.containsAll(c2));//true,判断c集合是否包含c2集合中的所有元素

        System.out.println(c.retainAll(c2));//取两集合之间的公共部分
        System.out.println(c);//[2, 4, 6]

//        System.out.println(c.removeAll(c2));//删除c集合中属于c2集合的所有元素
//        System.out.println(c);//[]

        //3.遍历/迭代集合中的元素
        /*1.获取集合对应的迭代器Iterator<E> it = c.iterator()
        * 2.判断集合中是否有下个元素it.hasNext()
        * 3.获取当前迭代到的元素it.next()*/
        //3.1获取集合的迭代器
        Iterator<Integer> it = c.iterator();
        //3.2通过循环变量集合
        while(it.hasNext()){//判断是否有下个元素,若有,继续循环,直到没有
            //3.3next()获取本类循环迭代到的元素
            Integer next = it.next();
            System.out.println(next);

        }


    }
}

2.3.3遍历/迭代集合中的元素

1).获取集合对应的迭代器Iterator it = c.iterator()
2).判断集合中是否有下个元素it.hasNext()
3).获取当前迭代到的元素it.next()

3.List接口

3.1有序集合接口:

1)对列表中的每个元素的插入位置进行精确的控制

2)根据元素的整数索引(在列表中的位置)来访问元素,并搜索列表中的元素

3)List接口集合可以使用Collection接口集合的常用方法,也可以使用部分数组的常用方法

3.2List接口的特点:

  1. 数据是有序的    
  2. 元素都有下标
  3. 允许存放重复的元素

3.3List接口常用方法:

注意:List接口集合可以使用Collection接口集合的常用方法,也可以使用部分数组的常用方法

List单个集合接口
add(1,"蝎子精")在有序集合中指定下标处添加元素
get(3)获取指定下标上的元素
indexOf("小蝴蝶")获取指定元素首次出现的索引(下标),不包含返回-1
lastIndexOf("小蝴蝶")获取指定元素最后一次出现的索引,不包含返回-1
remove(5)移除指定下标中的元素
set(3,"蛇精")修改指定下标处元素的值
list.subList(37)截取子串[3,7)左闭右开
List集合与集合之间的常用方法
addAll(list2)添加到末尾
addAll(0,list2)指定下标添加集合
contains(list2)判断集合中是否有一个元素叫list2
containsAll(list2)判断集合中是否包含集合list2
removeAll(list2)移除集合在属于集合2中的所有元素

练习1:List常用方法的测试

package cn.tedu.collection;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/*本类测试List接口方法*/
public class TestList {
    public static void main(String[] args) {
        //1.创建List接口多态对象,注意List是接口无法实例化
        List<String> list =new ArrayList<String>();

        //2.测试继承自Collection的方法
        list.add("大力娃");//向集合中添加元素
        list.add("千瞬娃");
        list.add("铁头娃");
        list.add("火娃");
        list.add("水娃");
        list.add("隐身娃");
        list.add("七娃");
        System.out.println(list);//打印查看集合

//        list.clear();//清空集合所有元素
//        System.out.println(list);

        System.out.println(list.contains("千瞬娃"));//是否包含指定元素

        System.out.println(list.equals("千瞬娃"));//判断指定的值与集合是否相等

        System.out.println(list.hashCode());//哈希码值

        System.out.println(list.isEmpty());//判断集合是否为空

        System.out.println(list.remove("大力娃"));//移除集合中首次出现指定的元素

        System.out.println(list.size());//获取集合的元素个数

        System.out.println(Arrays.toString(list.toArray()));//将集合转成数组并查看

        //3.List集合特有的方法--可以根据索引来操作的方式
        list.add("小蝴蝶");
        System.out.println(list);//[千瞬娃, 铁头娃, 火娃, 水娃, 隐身娃, 七娃, 小蝴蝶]

        list.add(1,"蝎子精");//在有序集合中指定下标处添加元素
        System.out.println(list);//[千瞬娃, 蝎子精, 铁头娃, 火娃, 水娃, 隐身娃, 七娃, 小蝴蝶]

        System.out.println(list.get(3));//水娃,获取指定下标上的元素

        list.add(3,"小蝴蝶");//指定下标添加元素
        System.out.println(list);

        System.out.println(list.indexOf("小蝴蝶"));//获取指定元素首次出现的索引(下标)
        System.out.println(list.lastIndexOf("小蝴蝶"));//获取指定元素最后一次出现的索引

        System.out.println(list.remove(5));//移除指定下标中的元素

        System.out.println(list.set(3,"蛇精"));//修改指定下标处元素的值
        System.out.println(list);//[千瞬娃, 蝎子精, 铁头娃, 蛇精, 火娃, 隐身娃, 七娃, 小蝴蝶]

        List<String> subList = list.subList(3, 7);//截取子串[3,7)左闭右开
        System.out.println(subList);//[蛇精, 火娃, 隐身娃, 七娃]

        //4.集合间的操作
        List<String> list2 = new ArrayList<>();//创建有序集合2对象

        list2.add("1");//向集合2添加元素
        list2.add("2");
        list2.add("3");
        System.out.println(list.addAll(list2));//添加到末尾
        System.out.println(list);//[千瞬娃, 蝎子精, 铁头娃, 蛇精, 火娃, 隐身娃, 七娃, 小蝴蝶, 1, 2, 3]

        System.out.println(list.addAll(0,list2));//指定下标添加集合
        System.out.println(list);//[1, 2, 3, 千瞬娃, 蝎子精, 铁头娃, 蛇精, 火娃, 隐身娃, 七娃, 小蝴蝶, 1, 2, 3]

        System.out.println(list.contains(list2));//false,判断集合中是否有一个元素叫list2
        System.out.println(list.containsAll(list2));//true,判断集合中是否包含集合list2

        System.out.println(list.removeAll(list2));//移除集合在属于集合2中的所有元素
        System.out.println(list);//[千瞬娃, 蝎子精, 铁头娃, 蛇精, 火娃, 隐身娃, 七娃, 小蝴蝶]



    }
}

练习2:List集合接口的4种遍历/迭代方式

list集合的迭代方式:
        * 1.for循环
        * 2.高效for循环
        * 3.iterator()
        * 4.listIterator():ListIterator()是Iterator的子接口,拥有逆向遍历的特有功能,但不常用

package cn.tedu.collection;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/*测试List接口的4种遍历方式*/
public class TestList2 {
    public static void main(String[] args) {
        //1.创建List接口的多态对象
        List<String> list = new ArrayList<>();

        //2.向集合中添加元素
        list.add("喜羊羊");
        list.add("美羊羊");
        list.add("懒羊羊");
        list.add("沸羊羊");
        list.add("慢羊羊");
        list.add("红太狼");
        System.out.println(list);

        //3.测试集合的迭代
        /*集合迭代的方式:
        * 1.for循环
        * 2.高效for循环
        * 3.iterator()
        * 4.listIterator()*/
        //方式1:由于list是有序的,可根据下标进行迭代
        //从下标为0处开始,最大下标是集合的元素个数减1
        for (int i =0;i<list.size();i++){
            System.out.print(list.get(i));//根据下标获取本轮循环得到的元素
        }
        System.out.println();
        System.out.println("=================================");

        //方式2:提高效率,高效for循环(每轮遍历到的元素类型  元素的名字 : 要遍历的内容){}
        for (String s : list){
            System.out.println(s);
        }
        System.out.println("**********************************");

        //方式3:iterator(),继承自父类Collection的迭代器
        Iterator<String> iterator = list.iterator();//迭代器
        //由于集合有很多元素,需要重复操作,所有使用循环结构
        while(iterator.hasNext()){//判断是否有下一个元素
            System.out.println(iterator.next());//打印本轮循环中获取的元素
        }
        System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");

        //方式4:ListItreator是List的迭代器
/*ListIterator()是Iterator的子接口,拥有逆向遍历的特有功能*/
        ListIterator<String> it2 = list.listIterator();
        while(it2.hasNext()){
            System.out.println(it2.next());
        }

    }
}

4.ArrayList

4.1概念:

  1. 存在java.util包中
  2. 内部是用数组结构存放数据,封装数组的操作,每个对象都有下标
  3. 内部数组默认的初始容量是10,如果不够会以1.5倍的容量增长
  4. 查询快,增删数据效率会低

练习:ArrayList的常用方法以及4中迭代方式

package cn.tedu.collection;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.ListIterator;

/*测试List接口的子类ArrayList*/
public class TestArrayList {
    public static void main(String[] args) {
        //1.创建对象,使用无参构造
        //底层会自动创建数组帮我们存放集合对象,数组的初始容量为10
        ArrayList<Integer> list = new ArrayList<>();

        //2.存入一些数据
        list.add(100);
        list.add(200);
        list.add(300);
        list.add(400);
        list.add(200);

        //3.测试ArrayList接口的方法
//        list.clear();
//        System.out.println(list);

        System.out.println(list.contains(100));//true,包含指定元素

        System.out.println(list.get(1));//200,获取下标1的元素

        System.out.println(list.indexOf(200));//1,获取第一次出现指定元素的下标
        System.out.println(list.lastIndexOf(200));//4,获取指定元素最后一次出现时的下标

        System.out.println(list.remove(1));//移除指定下标下的元素
        System.out.println(list);//[100, 300, 400, 200]

        /*注意:写法报错:
        * 300默认是int,会匹配根据索引删除元素的方法,所以需要int转成Integer
        * 才会匹配根据指定元素来删除的方法*/
        //System.out.println(list.remove(300));
        //int类型转成包装类Integer,手动装箱
        System.out.println(list.remove(Integer.valueOf(300)));

        System.out.println(list.size());//获取集合元素个数

        System.out.println(Arrays.toString(list.toArray()));//list数组集合转为普通数组

        //4.4种迭代/遍历方式
        //方式1:
        System.out.println("方式1:for循环");
        for (int i = 0;i<list.size();i++){
            System.out.println(list.get(i));
        }
        System.out.println("方式2:高效for循环");

        for (Integer i :list){
            System.out.println(i);
        }

        System.out.println("方式3:iterator()");
        Iterator<Integer> it = list.iterator();
        while(it.hasNext()){
            Integer next = it.next();
            System.out.println(next);
        }
        System.out.println("方式4:listIterator()");
        ListIterator<Integer> it2 = list.listIterator();
        while(it2.hasNext()){
            Integer next = it2.next();
            System.out.println(next);
        }
    }
}

5.链表LinkedList

5.1面试题:LinkedList链表与ArrayList数组的区别?

答:1)ArrayList是一个集合,底层维护的是一个数组结构
数组结构:查询快,增删慢

2)LinkedList是一个集合,底层维护的是一个链表结构
链表结构:查询慢,增删快
TIPS:两者指的都是数据量比较大的情况,而且链表首尾操作还是比较快的,中间反而慢

练习:链表的常用方法以及特有方法

注意:链表常用方法继承自Collection中的方法

除了集合的方法外,LinkedList还有自己特有的方法

查询方法:
element()/peek()获取指定集合所有元素
peekFirst()/peekLast()获取集合第一个/最后一个元素
增加方法:
offer()        指定元素添加到集合中
offerFirst()/offerLast()指定元素添加到集合的首位/末位
移除方法:
pool()移除元素(默认移除首位)
poolFirst()/poolLast()移除集合中的首位/末位元素
package cn.tedu.collection;

import java.util.LinkedList;

/*测试链表的常用方法,特有方法测试*/
public class TestLinkedList {
    public static void main(String[] args) {
        //1.创建集合对象
        LinkedList<String> list = new LinkedList<>();

        //2.添加数据
        list.add("唐三藏");
        list.add("孙悟空");
        list.add("猪八戒");
        list.add("沙悟净");
        list.add("白龙马");
        System.out.println(list);

        //3.1自行测试继承自Collection中的方法

        //3.2LinkedList特有方法测试
        list.addFirst("蜘蛛精");//添加首元素
        list.addLast("玉兔精");//添加尾元素
        System.out.println(list);//[蜘蛛精, 唐三藏, 孙悟空, 猪八戒, 沙悟净, 白龙马, 玉兔精]

        System.out.println(list.getFirst());//获取首元素
        System.out.println(list.getLast());//获取尾元素

        System.out.println(list.removeFirst());//蜘蛛精,删除首元素
        System.out.println(list.removeLast());//玉兔精,删除尾元素
        System.out.println(list);

        //4.其他测试
        //4.1创建对象
        LinkedList<String> list1 = new LinkedList<>();
        //4.2添加数据
        list1.add("西游记");
        list1.add("红楼梦");
        list1.add("三国演义");
        list1.add("水浒传");
        System.out.println(list1);

        /*别名:查询系列*/
        System.out.println(list1.element());//获取但不移除集合的首元素
        System.out.println(list1.peek());//西游记,获取集合中的首元素但不移除
        System.out.println(list1.peekFirst());//西游记,获取但不移除集合中的首元素

        System.out.println(list1.peekLast());//水浒传,获取但不移除集合中的尾元素
        System.out.println(list1);

        /*别名:新增系列*/
        System.out.println(list1.offer("雪中悍刀行"));//指定元素添加在集合的末尾
        System.out.println(list1.offerFirst("吞噬星空"));//添加在首元素
        System.out.println(list1.offerLast("完美世界"));//添加在尾元素
        System.out.println(list1);

        /*别名:移除系列*/
        System.out.println(list1.poll());//吞噬星空,获取并移除集合中的首元素
        System.out.println(list1.pollFirst());//西游记,获取并移除集合首元素
        System.out.println(list1.pollLast());//完美世界,获取并移除集合尾元素
        System.out.println(list1);




    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值