集合框架越强大,我们越要打得他们落花流水,看集合框架是怎样被

这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

集合框架

集合概念

1、JAVA集合框架( Java Collection Framework ),又被称为容器(container),是定义在 java.util 包下的一组接口(interfaces)和其实现类(classes)
2、其主要表现为将多个元素(elements)置于一个单元中,用于对这些元素进行快速、便捷的存储、检索、管理,即增删查改(CRUD)

类和接口总览

在这里插入图片描述

Collection接口

//集合必写<>
    public static void main(String[] args) {
        Collection<String> collection1=new 
        LinkedList<>();
        Collection<Integer> collection=new
         ArrayList<>();
        collection.add(123);
        collection.add(5468);
        System.out.println(collection);
        
        Object[] arr=collection.toArray();
        System.out.println(Arrays.toString(arr));
//      数组整体不能进行强制类型转换
//      Integer[] array=(Integer[])collection.toArray();
//      System.out.println(array.toString());
    }
复制代码

集合必写<>
< 一定要写包装类 >

Collection接口常用方法

Collection
boolean add(E e) 尾插e
void clear() 删除集合中所有元素
Boolean isEmpty() 判断集合中是否没有任何元素(集合长度为0)
boolean remove(Object e) 如果e出现在集合中,删除第一个
int size() 返回集合中元素个数
Object[ ] toArray() 返回一个装有集合中所有元素的数组

在这里插入图片描述

泛型(Generic)

引入泛型的目的是为了提高代码的通用性
如下面的MyArrayList 类,可以通过对T的改变,使这个MyArrayList可以放String (MyArrayList< String >),也可以放Integer(MyArrayList< Integer >)

泛型类

class MyArrayList<T>{
    private T[] arr;
    private int useSizes;
    public MyArrayList(){
        this.arr=(T[])new Object[10];
//      擦除机制    编译时T被擦成Object,最后T就是Object
//      不存在数组不能整体进行强制类型转换的问题
//      Integer[] array=(Integer[])collection.toArray();
    }
    public void add(T val){
        this.arr[this.useSizes++]=val;
    }
    public T getPos(int pos){
        return this.arr[pos];
    }
}
    public static void main(String[] args) {
        MyArrayList<Integer> myArrayList=new MyArrayList<>();
        myArrayList.add(1);
        myArrayList.add(2);
        myArrayList.add(3);
        int ret=myArrayList.getPos(2);
        System.out.println(ret);
        MyArrayList<String> myArrayList2 = new MyArrayList<>()
    }
复制代码
  1. < T >代表当前类是一个泛型类,尖括号< >是泛型的标记

  2. 不能new泛型类型的数组,如:T[ ] arr = new T[10];

  3. 泛型的意义

(1)、在存储元素的时候,可以自动进行类型检查
(2)、在获取元素的时候,可以自动进行类型的转换
4. 泛型类型的参数( < T > )不能是简单类型,要用包装类T可以是任意包装类
5. 泛型类可以一次有多个类型变量,用逗号分割

泛型的编译

  1. 泛型只在编译时起作用,在运行时没有泛型的概念
  2. 擦除机制

编译时,将类中的< E >擦成Object(可以给擦除边界) MyArrayList< Integer > 和 MyArrayList< String >在编译时
< Integer >和< String >被擦掉,所以在运行期间两者是同一类型

类型边界

E是Number的子类或者是Number本身

public class Algorithm< T extends Number>{
    public T[] array;
//    public Algorithm (){
//        this.array =(T[])new Object[10];
//    }
//  写个寻找最大值的方法
    public T findMax(T[] array){
    
    }
}
复制代码
        Algorithm<String> a = new Algorithm<>();   //No
        Algorithm<Integer> aa = new Algorithm<>(); //OK
复制代码

擦除边界

擦除边界即泛型的上界
引用的比较一定要借助Comparable接口或Comparator接口的方法,泛型擦到Object;
Object没有实现Comparable或Comparator接口,不能调用compareTo()或compare()无法比较
在这里插入图片描述

给一个擦除边界,T会被擦到实现Comprable接口的地方,T一定会实现这个接口的
泛型只有上界,没有下界

class Algorithm<T extends Comparable<T>>{
    public T[] array;
//    public Algorithm (){
//        this.array =(T[])new Object[10];
//    }
    public T findMax(T[] array){
        T max = array[0];
        for (int i = 0; i < array.length; i++) {
            if(max.compareTo(array[i]) < 0){
                max = array[i];
            }
        }
        return max;
    }
}
复制代码

通配符

?用于泛型中,叫通配符

class Algorithm<T>{

}
public static void printAll(MyArrayList<?> list){

}
printAll(new MyArrayList<Integer>())
printAll(new MyArrayList<String>())
printAll(new MyArrayList<Person>())
复制代码

包装类( Wrapper Class )

在这里插入图片描述

装箱(boxing)和自动拆箱(unboxing)

public static void main1(String[] args) {
        //自动装箱
        int a=10;
        Integer b=a;
//        Double b1=a;  不可以
        //手动装箱
        Integer c=Integer.valueOf(a);
        Double c1=Double.valueOf(a);

//拆箱,咋拆都行
        //自动拆箱
        Integer m=10;
        int n=m;
        double n1=m;
        //手动拆箱
        int n2=m.intValue();
        double n3=m.doubleValue();
        byte n4=m.byteValue();
    }
复制代码

List

ArrayList 常见方法
boolean add(E e) 尾插e ,可以是null
void add(int index , E element) 指定位置插入e
boolean addAll(Collection< ?extends E > c) 插入c中的元素,实现Collection接口的都可以,可用于将一个List插入到另一个List中,但是不能插入null
E remove(int index) 删除指定位置的元素,删除的同时返回,删完向前补
boolean remove (E o) 删除第一个遇到的o
E get( int index) 获取元素
E set(int index , E elements) 将index位置的元素替换为elements,返回此位置原来的元素
boolean contains(E o) 判断o是否在线性表中
int indexOf(E o ) 返回第一个o所在的下标
int lastIndexOf( E o) 返回最后一个o所在的下标
List< E > subList(int fromIndex, int toIndex) 截取部分list(1、左闭右开 [ fromIndex ,toIndex) 2、subList并不是截取出来一个新的数组,而是原来的数组,相当于一个新的引用指向原来数组的一部分,改变返回的得到的数组,原来的数组也会改变)
   public static void main(String[] args) {
        List<Integer> list=new ArrayList<>();
        list.add(100);
        list.add(200);
        list.add(300);
        System.out.println(list);

//        boolean a = list.contains(100);
//        System.out.println(a);
//
//        int b = list.indexOf(200);
//        System.out.println(b);

        List<Integer> elist=list.subList(0,2);
        //前闭后开
        System.out.println(elist);
        //subList并不是截取出来一个新的数组,而是原来的数组
        elist.set(1,800);
        System.out.println(list);
    }
复制代码

在这里插入图片描述

迭代器 Iterator

  1. 用来打印集合中的元素
  2. 集合一定要实现Iterable接口才能用迭代器,才能调用集合对象中的iterator()方法,创建一个迭代器对象
  3. Iterator迭代器对象在遍历集合时,内部采用指针的方式来跟踪元素
  4. 在第一次调用next()前,迭代器对象的索引在第一个元素之前,通过hasNext()判断有无下一个元素,若有的话,打印;没有,退出循环,打印完成

三种打印方式

public static void main1(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(5);
        list.add(6);
        list.add(7);
        list.add(1,8);
        
        System.out.println(list);
        System.out.println("=============================");
        //迭代器
        Iterator<Integer> iterator = list.iterator();
        while(iterator.hasNext()){                                  //判断是否有下一个
            System.out.println(iterator.next());                    //不光是打印,而且iterator向下走
        }

        System.out.println("==============================");
        for (Integer x :list) {
            System.out.println(x);
        }
    }
复制代码

在这里插入图片描述

扑克牌

首先创建一张牌
一张牌需要有数字、花色

class Card{
    private int rank;
    private String suit;
    public Card(int rank, String suit) {
        this.rank = rank;
        this.suit = suit;
    }
    public int getRank() {
        return rank;
    }
    public void setRank(int rank) {
        this.rank = rank;
    }
    public String getSuit() {
        return suit;
    }
    public void setSuit(String suit) {
        this.suit = suit;
    }
    @Override
    public String toString() {
        return "[ "+suit+","+rank+" ]";
    }
}
复制代码

然后创建一个类:进行对一副牌的操作
首先要买一副牌:把每张牌都放到一个集合中
洗牌:从前往后遍历这副牌,让每一张牌都与后面的随机一张牌交换位置,由于random的取值范围只能从零开始,如下标为6的牌,Index属于[0,9],可能Index是5,与上行的逻辑不符
从后往前遍历这副牌,让每一张牌都与前面的随机一张牌交换位置, 下标9的牌与Index属于[0,9)的牌交换 , 8--Index属于[0,8), 6--Index属于[0,6)

class cardDemo{
    public static final String[] suit = {"♥","♠","♦","♣"};

    //买一副牌
    public List<Card> buy(){
        List<Card> deskcard = new ArrayList<>();
        for (int i = 0; i <suit.length; i++) {
            for (int j = 1; j <=13 ; j++) {
                Card card = new Card(j,suit[i]);
                deskcard.add(card);
            }
        }
        return deskcard;
    }

    //交换
    public void swap(List<Card> desk,int i,int index){
//        Card tmp=desk[i];
//        desk[i]=desk[Index];
//        desk[Index]=tmp;
        Card tmp=desk.get(i);
        desk.set(i,desk.get(index));
        desk.set(index,tmp);
    }

    //洗牌
    public void shuff(List<Card> desk){
        int len = desk.size();
        //此处逻辑重点,从后往前,每一张牌都与前面随机的一张牌交换
        for (int i = len-1; i > 0 ; i--) {
            Random random = new Random();
            //取一个[0,i)间的随机数
            int index = random.nextInt(i);
            swap(desk,i,index);
        }
    }
}
复制代码

玩牌:三个人轮流摸五张牌,即进行5轮,每轮摸三张牌。
创建三个集合,代表三个人手中的牌,也可以在创建一个集合,放三个人手中的牌


public class TestDemo2 {
    //三个人轮流摸5张牌
    public static void game(List<Card> desk ){
        System.out.println("玩牌!!!");
        ArrayList<Card> hand1=new ArrayList<>();
        ArrayList<Card> hand2=new ArrayList<>();
        ArrayList<Card> hand3=new ArrayList<>();
//        for (int i = 0; i <5 ; i++) {
//            Card card1=desk.remove(0);
//            hand1.add(card1);
//            Card card2=desk.remove(0);
//            hand2.add(card2);
//            Card card3=desk.remove(0);
//            hand3.add(card3);
//        }
        ArrayList< ArrayList<Card> > hand=new ArrayList<>();
        hand.add(hand1);
        hand.add(hand2);
        hand.add(hand3);
        for (int i = 0; i <5 ; i++) {
            for (int j = 0; j <3 ; j++) {
                Card card=desk.remove(0);
                hand.get(j).add(card);
            }
        }

        //每个人一次性的摸5张牌
//        for (int i = 0; i <3 ; i++) {
//            for (int j = 0; j <5 ; j++) {
//
//            }
//        }


        for (int i = 0; i <hand.size() ; i++) {
            System.out.println(hand.get(i));
        }
    }

    public static void main(String[] args) {
        cardDemo caeddemo = new cardDemo();
        List<Card> desk = caeddemo.buy();
        System.out.println(desk);
//        List<Card> desk = buy();
//        System.out.println(desk);
        System.out.println("洗牌:");
        caeddemo.shuff(desk);
        System.out.println(desk);

        game(desk);
        System.out.println(desk);
    }
}

复制代码

杨辉三角

public static List< List<Integer> > yanghui(int number) {
        if (number == 0) {
            return null;
        }
        List<List<Integer>> list = new ArrayList<>();
        //添加第一组
        List<Integer> list1 = new ArrayList<>();
        list1.add(1);
        list.add(list1);
        for (int i = 1; i < number; i++) {
            List<Integer> elist = new ArrayList<>();
            //每组第一个数是1
            elist.add(1);
            //找到上一行的list
            List<Integer> prelist = list.get(i - 1);
            for (int j = 1; j < i ; j++) {
                //上一行与之同列的数+上一行前一列的数
                elist.add(prelist.get(j) + prelist.get(j - 1));
            }
            //每组最后一个是1
            elist.add(1);
            list.add(elist);
        }

        return list;
    }
    public static void main(String[] args) {
        List< List<Integer> > list = yanghui(5);
        for (List<Integer> arr:list) {
            System.out.println(arr);
        }
    }
复制代码

将"welcome come to bit"中的 "come"中所存在的字符 去掉 变为"wl t bit"
思路:建立一个新的集合,遍历str1的字符,判断str2中是否存在此字符,如果不存在,将此字符拿到这个新集合中

public static void main(String[] args) {
        String str1 = "welcome come to bit";
        String str2 = "come";
        List<Character> list = new ArrayList<>();
        for (int i = 0; i <str1.length(); i++) {
            char ch=str1.charAt(i);
            if(!str2.contains(ch+"")){
                list.add(ch);
            }
        }
        System.out.println(list);
        for (int i = 0; i <list.size() ; i++) {
            System.out.print(list.get(i));
        }
    }
复制代码

老铁们,关注博主,让我们继续乘胜追击在这里插入图片描述