Day15-集合(Collection、红黑树 (List&Set )并发修改异常,泛型深入)

目录

一. Collextion(单列集合接口)

1. Collection集合体系特点

2.Collection集合常用API

3.Collection集合的遍历方式

①方式一:迭代器

②方式二:foreach/增强for循环

③方式三:lambda表达式

4.Collection集合存储自定义类型的对象

5. 补充知识:集合工具类Collections  

 6.  总结

二.  List

1.  List集合特点、特有API、遍历方式

2.  ArrayList集合的底层原理

 3. LinkedList集合特点、特有API

三. Set  

1.  Set系列集系概述

 2. HashSet元素无序的底层原理:哈希表

3. HashSet元素去重复的底层原理

 4.实现类:LinkedHashSet

 5. 实现类:TreeSet

四. 红黑树                                java.util.List

五. 集合的并发修改异常问题                               

六.  泛型深入                               

  1. 自定义泛型类

  2.  自定义泛型方法

  3.   自定义泛型接口

 4. 泛型通配符、上下限


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

一. Collextion(单列集合接口)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

1. Collection集合体系特点

2.Collection集合常用API

   

  代码演示:

public class Test {
    public static void main(String[] args) {

        Collection<String> col = new ArrayList<>();
        
        //1. 添加元素
        col.add("库里");
        col.add("汤普森");
        col.add("格林");
        col.add("库里");
        col.add("汤普森");
        col.add("格林");
        System.out.println(col);

        //2. 清空所有元素
        col.clear();
        System.out.println(col);

        // 3. 删除某个元素: 如果有多个重复元素默认删除前面的第一个!
        col.remove("库里");
        System.out.println(col);

        //4. 判断集合是否为空
        boolean rs = col.isEmpty();
        System.out.println(rs);

        //5. 判断集合是否包含指定内容
        boolean result = col.contains("格林");
        System.out.println(result);

        //6. 计算集合元素大小
        int num = col.size();
        System.out.println(num);

        //7.  集合转数组
        //注意Object 和 Objects 的区别  Objects会报错
        Object[] arrs = col.toArray();
        System.out.println(Arrays.toString(arrs));

        // 8. addAll 全部添加
        Collection<String> c1 = new ArrayList<>();
        c1.add("java1");
        c1.add("java2");

        Collection<String> c2 = new ArrayList<>();
        c2.add("赵敏");
        c2.add("殷素素");

        // addAll把c2集合的元素全部拷贝到c1中去。
        c1.addAll(c2);
        System.out.println(c1);
        System.out.println(c2);
    }

3.Collection集合的遍历方式

①方式一:迭代器

    

  代码演示:

public static void main(String[] args) {
        Collection<String> lists = new ArrayList<>();
        lists.add("赵敏");
        lists.add("小昭");
        lists.add("素素");
        lists.add("灭绝");
        System.out.println(lists);
      
        // 1、得到当前集合的迭代器对象。
        Iterator<String> it = lists.iterator();

        // 2、定义while循环
        while (it.hasNext()){
            String ele = it.next();
            System.out.println(ele);
        }
    }

②方式二:foreach/增强for循环

代码演示: 

public static void main(String[] args) {

        Collection<String> col = new ArrayList<>();
        col.add("赵敏");
        col.add("小昭");

        //快捷键:col.for  回车
        for (String ck : col) {
            System.out.println(ck);
        }

        double[] arrs = {1.2, 3.6, 4.5, 9.9, 12.2};
        for (double arr : arrs) {
            //修改无意义,不会影响数组的元素值,每次都只是拷贝一份到第三方变量
            //score = 100.0;
            System.out.println(arr);
        }
    }

③方式三:lambda表达式

4.Collection集合存储自定义类型的对象

        案例:某影院系统需要在后台存储上述三部电影,然后依次展示出来。

5. 补充知识:集合工具类Collections  

代码演示:

//Collections 的 addAll 和shuffle sort①

public class CollectionsDemo01 {
    public static void main(String[] args) {
        List<String> names = new ArrayList<>();

        Collections.addAll(names, "楚留香","胡铁花", "张无忌","陆小凤");
        System.out.println(names);

        // 2、public static void shuffle(List<?> list) :打乱集合顺序。
        Collections.shuffle(names);
        System.out.println(names);

        // 3、 public static <T> void sort(List<T> list):将集合中元素按照默认规则排序。 (排值特性的元素)
        List<Integer> list = new ArrayList<>();
        Collections.addAll(list, 12, 23, 2, 4);
        System.out.println(list);
        Collections.sort(list);
        System.out.println(list);
    }
}
---------------------------------------------------------------------
sort②

//苹果类
public class Apple {
    private String name;
    private String color;
    private double price;
    private int weight;
}

//测试类
public class CollectionsDemo02 {
    public static void main(String[] args) {
        List<Apple> apples = new ArrayList<>(); // 可以重复!
        apples.add(new Apple("红富士", "红色", 9.9, 500));
        apples.add(new Apple("青苹果", "绿色", 15.9, 300));
        apples.add(new Apple("绿苹果", "青色", 29.9, 400));
        apples.add(new Apple("黄苹果", "黄色", 9.8, 500));

        // 方法一:可以的,Apple类已经重写了比较规则
       Collections.sort(apples);
      System.out.println(apples);

        // 方式二:sort方法自带比较器对象
        Collections.sort(apples, ( o1,  o2) ->  Double.compare(o1.getPrice() , o2.getPrice()) );
        System.out.println(apples);
    }
}

 6.  总结

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

二.  List

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

1.  List集合特点、特有API、遍历方式

 代码演示:

public static void main(String[] args) {

       List<String> list=new ArrayList<>();
       list.add("库里");
       list.add("库里");
       list.add("汤普森");
       list.add("格林");
        System.out.println(list);

        // 1.在某个索引位置插入元素。
        list.add(1,"麦科勒姆");
        System.out.println(list);

        // 2.根据索引删除元素,返回被删除元素
        list.remove(3);
        System.out.println(list);

        // 3.修改索引位置处的元素: public E set(int index, E element)
        list.set(0,"库里FMVP");
        System.out.println(list);

        // 4.根据索引获取元素:public E get(int index):返回集合中指定位置的元素。
        String s = list.get(1);
        System.out.println(s);
    }

List集合的遍历方式有几种?

①迭代器         ②增强for循环         ③Lambda表达式        ④for循环(因为List集合存在索引)

2.  ArrayList集合的底层原理

 

 3. LinkedList集合特点、特有API

 

 代码演示:

        public static void main(String[] args) {
            // LinkedList可以完成队列结构,和栈结构 (双链表)
            // 1、做一个队列:
            LinkedList<String> queue = new LinkedList<>();
            // 入队
            queue.addLast("1号");
            queue.addLast("2号");
            queue.addLast("3号");
            System.out.println(queue);
            // 出队
            // System.out.println(queue.getFirst());
            System.out.println(queue.removeFirst());
            System.out.println(queue.removeFirst());
            System.out.println(queue);

            // 2、做一个栈
            LinkedList<String> stack = new LinkedList<>();
            // 入栈 压栈 push和addFirst一样
            
            stack.push("第1颗子弹");
            stack.push("第2颗子弹");
            stack.push("第3颗子弹");
            System.out.println(stack);

            // 出栈  弹栈 pop和removeFirst一样
            stack.removeFirst();
            stack.pop();
        }

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

三. Set  

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

1.  Set系列集系概述

 2. HashSet元素无序的底层原理:哈希表

3. HashSet元素去重复的底层原理

 4.实现类:LinkedHashSet

 5. 实现类:TreeSet

 两种方式举例:

//方式一 实现Comparable接口,重写compare方法
public class Apple implements Comparable<Apple>{
            //这里实现 Comparable是关键        ****
    private String name;
    private String color;
    private double price;
    private int weight;

    @Override
    public String toString() {
        return "Apple{" +
                "name='" + name + '\'' +
                ", color='" + color + '\'' +
                ", price=" + price +
                ", weight=" + weight +
                '}';
    }

    @Override
    public int compareTo(Apple o) {
        // 去重重量重复的元素
        return this.weight - o.weight ;
        // 保留重量重复的元素
        // return this.weight - o.weight >= 0 ? 1 : -1;
    }
}

//测试类
public static void main(String[] args) {

        Set<Apple> apples = new TreeSet<Apple>();
        apples.add(new Apple("红富士", "红色", 9.9, 500));
        apples.add(new Apple("青苹果", "绿色", 15.9, 300));
        apples.add(new Apple("绿苹果", "青色", 29.9, 400));
        apples.add(new Apple("黄苹果", "黄色", 9.8, 500));
        System.out.println(apples);
    }


//方式二  设置Comparator接口对应的比较器对象,来定制比较规则。
        TreeSet<student> students=new TreeSet<>(new Comparator<student>() {
             @Override
             public int compare(student o1, student o2) {
                 return o1.getAge()-o2.getAge();
             }
         });

         TreeSet<student>  students1=new TreeSet<>((o1, o2) -> o1.getAge()-o2.getAge());

 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

四. 红黑树                                java.util.List

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

五. 集合的并发修改异常问题                               

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

代码演示: 

public static void main(String[] args) {

        ArrayList<String> list = new ArrayList<>();
        list.add("黑马");
        list.add("Java");
        list.add("Java");
        list.add("赵敏");

        // 需求:删除全部的Java信息。
        // a、迭代器遍历删除
        Iterator<String> it = list.iterator();
        while (it.hasNext()){
            String ele = it.next();
            if("Java".equals(ele)){
                // list.remove(ele); // 集合删除会出毛病
                it.remove(); // 迭代器删除所在位置的元素,可保证不后裔
            }
        }
        System.out.println(list);

        // b、foreach遍历删除 (会出现问题,这种无法解决的,foreach不能边遍历边删除,会出bug)
        for (String s : list) {
            if("Java".equals(s)){
                list.remove(s);
            }
        }

        // c、lambda表达式(会出现问题,这种无法解决的,Lambda遍历不能边遍历边删除,会出bug)
        list.forEach(s -> {
            if("Java".equals(s)){
                list.remove(s);
            }
        });

        // d、for循环(边遍历边删除集合没毛病,但是必须从后面开始遍历删除或者每次删除后i--)
        for (int i = list.size() - 1; i >= 0 ; i--) {
            String ele = list.get(i);
            if("Java".equals(ele)){
                list.remove(ele);
            }
        }
    } 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

六.  泛型深入                               

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  

  1. 自定义泛型类

 案例:

               要求:模拟ArrayList集合自定义一个集合MyArrayList集合,完成添加和删除功能的泛型设计                        

//定义泛型类
public class MyArrayList<E> {

    //内部new一个ArrayList
    private ArrayList<E> list=new ArrayList<>();

    public  void  add(E e){
        list.add(e);
    }

    public  void  remove(E e){
        list.remove(e);
    }

    //重写toString方法
    @Override
    public String toString() {
        return list.toString();
    }
}

//测试类
public class Test {
    public static void main(String[] args) {

        MyArrayList<String> list = new MyArrayList<String>();
        list.add("黑马");
        list.add("Java");

        System.out.println(list);
    }
}

  2.  自定义泛型方法

 案例:

        给你任何一个类型的数组,都能返回它的内容。也就是实现Arrays.toString(数组)的功能!

public class GenericDemo {
    public static void main(String[] args) {
        String[] names = {"小璐", "蓉容", "小何"};
        printArray(names);

        Integer[] ages = {10, 20, 30};
        printArray(ages);

        Integer[] ages2 = getArr(ages);
        String[]  names2 = getArr(names);
    }


    //可以定义返回值为数组的方法 
    public static <T> T[] getArr(T[] arr){
        return arr;
    }

    public static <T> void printArray(T[] arr){
        if(arr != null){
            StringBuilder sb = new StringBuilder("[");
            for (int i = 0; i < arr.length; i++) {
                sb.append(arr[i]).append(i == arr.length - 1 ? "" : ", ");
            }
            sb.append("]");
            System.out.println(sb);
        }else {
            System.out.println(arr);
        }
    }
}

  3.   自定义泛型接口

 案例:

                教务系统,提供一个接口可约束一定要完成数据(学生,老师)的增删改查操作

//学生类
public class student {
    
}

//接口
public interface date<E>{
    void add(E e);
    void delete(E e);
}

//实现类: 注意 类名< >
public class studentDate implements date<student>{
    @Override
    public void add(student s) {   }

    @Override
    public void delete(student s) {    }
}

//测试类
public class Test {
    public static void main(String[] args) {
        student s=new student();
        studentDate st=new studentDate();
        st.add(s);
    }
}

 4. 泛型通配符、上下限

 案例:

               开发一个极品飞车的游戏,所有的汽车都能一起参与比赛

public class GenericDemo {
    public static void main(String[] args) {

        //虽然BMW和BENZ都继承了Car
        //但是ArrayList<BMW>和ArrayList<BENZ>与ArrayList<Car>没有关系的!!

        //宝马车集合
        ArrayList<BMW> bmws = new ArrayList<>();
        bmws.add(new BMW());
        bmws.add(new BMW());
        go(bmws);

        //奔驰车集合
        ArrayList<BENZ> benzs = new ArrayList<>();
        benzs.add(new BENZ());
        benzs.add(new BENZ());
        go(benzs);

        //狗集合
        ArrayList<Dog> dogs = new ArrayList<>();
        dogs.add(new Dog());
        dogs.add(new Dog());
        // go(dogs);
    }

       //所有车比赛方法
    public static void go(ArrayList<? extends Car> cars){
    }
}

class Dog{

}

class BENZ extends Car{
}

class BMW extends Car{
}

// 父类
class Car{
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值