Java中的集合

知识模块
    a.为什么需要集合?
    b.集合的通用功能
       1.集合添加,获取功能
       2.集合的判断功能
       3.集合的删除功能
       4.集合的迭代
       5.泛型


一.集合
  a.为什么需要集合?
     存储班级中80个同学的成绩 ?
    第一种方法:使用变量存储
       int student01 = 50;
       int student02 = 70;
       int student03 = 80;
       ......
       int student80 = 76;
    第二种方法:使用数组存储
       int[] scores = new int[80];
       scores[0] = 80;
       scores[1] = 90;
       .....
       scores[79] = 100;
    后来又来了20个同学,存储这20个同学的成绩 ?
    由于长度为80的数组已经存满,我们无法在存储这20个同学的成绩,想要存储,我们需要在开辟一个长度位100的数组
       int[] new Scores = new int [100];
       newScores[0]~newScores[79]  存储原来80个人的成绩
       newSorces[80]~newScores[99] 存储新来的20个人的成绩
    都三种方法:
       我们使用别人写好的类来存储元素,我们不需要关心空间不够的情况
       我们只需要关心元素的存储,取出,删除...这一系列操作元素的行为
       那么这个类或者这个类的体系就是集合

  b.集合的通用功能
     1.集合添加,获取功能
        /*
        集合体系通用功能:
         boolean add(Object e)
                  确保此 collection 包含指定的元素(可选操作)。
                  像集合中添加元素

         int size()
                  返回此 collection 中的元素数。
               获取数组长度,使用length属性,arr.length
               获取字符串的长度,使用String类中的length()方法,"abc".length()
               获取StringBuilder长度,使用StringBuilder类中的length()方法,new StringBuilder("abc").length();
               获取集合元素中的元素个数,使用集合的size()方法

         void clear()
                  移除此 collection 中的所有元素(可选操作)。
         */
public class CollectionDemo01 {
    public static void main(String[] args) {
        //method01();
        //method02();
        Collection c = new ArrayList();
        c.add("abc");
        c.add("f");
        c.add("mhk");
        System.out.println(c);//[abc, f, mhk]
        c.clear();//清空集合中元素
        System.out.println(c);//[]
    }

    private static void method02() {
        Collection c = new ArrayList();
        c.add(123);//Object e = 123
        //装箱 Object e = new Integer(123)
        c.add("abc");
        c.add(456);
        c.add("def");
        System.out.println(c.size());
    }

    private static void method01() {
        Collection c = new ArrayList();//父接口指向实现对象  多态
        c.add("abc");//Object e = "abc";  父类引用指向子类对象 多态
        c.add("def");
        System.out.println(c);//[abc, def]  集合底层重写了toString()方法
        System.out.println(c.toString());
    }
}
     2.集合的判断功能
          boolean contains(Object o)
                   判断集合中是否包含指定元素,如果包含,返回true
                                           不包含,返回false
                   contains()方法底层判断元素是否包含在集合中,他其实依赖的是存储元素的boolean equals(Object obj)方法
                   int[] arr{13,15,17,19}
                 Person p1 = new Person("无忌", 19);
                 Person p2 = new Person("敏敏", 18);
                 c.add(p1);  //p3和p1比较,其实就是调用equals()方法,相当于p3.equals(p1),Person类中默认的equals()方法,比较的是内存地址值
                 c.add(p2);  //p3和p2比较,其实就是调用equals()方法,相当于p3.equals(p2),Person类中默认的equals()方法,比较的是内存地址值

                 Person p3 = new Person("无忌", 19);
                 System.out.println(c.contains(p3)); //当所有元素都调用equals()方法和p3比较,都返回flase,说明这个集合中不包含p3
                                                     //最终contains方法会false

          boolean isEmpty()
                   判断集合是否有元素,如果有元素,返回false
                                      无元素,返回true
public class CollectionDemo02 {
    public static void main(String[] args) {
        //method01();
        //method02();
        Person p1 = new Person("无忌", 19);
        Person p2 = new Person("敏敏", 18);
        Collection c = new ArrayList();
        c.add(p1);//Object e = p1 = new Person("无忌",19);  多态
        c.add(p2);
        System.out.println(c);//[collection01.Person@4eec7777, collection01.Person@3b07d329]
        //集合中的元素也会调用toString()方法
        Person p3 = new Person("无忌", 19);
        System.out.println(c.contains(p3));//    //当所有元素都调用equals()方法和p3比较,都返回flase,说明这个集合中不包含p3
                                                 //最终contains方法会false
                                                 //当我们重写了Person类中equals()方法,比较姓名和年龄,
                                                 //此时p3和p1都是一样的,所以认为集合中包含这个人,返回true
        Person p4 = new Person("无忌", 21);
        System.out.println(c.contains(p4));//false

    }

    private static void method02() {
        Collection c = new ArrayList();
        c.add("张三");
        c.add("李四");
        c.add("王五");
        System.out.println(c.contains("李四"));//true
        System.out.println(c.contains("赵六"));//false
    }

    private static void method01() {
        Collection c = new ArrayList();
        c.add("abc");
        c.add("def");
        System.out.println(c.isEmpty());//false
        c.clear();
        System.out.println(c.isEmpty());//true
    }
}
     3.集合的删除功能
          集合中的移除功能:
               boolean remove(Object o)
                    从集合中移除指定的元素,如果移除成功,返回true,否则返回false
                    remove()方法依靠集合中的equals()方法比较,如果两个元素调用equals()方法返回true说明存在元素,可以移除,返回true
                            如果集合中所有元素调用equals()与被移除元素比较,都返回false,集合中不存该元素,移除失败,返回false

                  Person p1 = new Person("乔峰", 30);
                  Person p2 = new Person("阿朱", 20);
                  c.add(p1);
                  c.add(p2);

                  Person p3 = new Person("乔峰", 30);

                  System.out.println(c.remove(p3));//首先跟p1比较,p1.equals(p3),如果调用Object里面的equals()方法,默认比较地址值,返回false


                  int[] arr = {15,19,21}
                  移除19
                  移除16

               contains()方法与remove()方法底层在判断的时候都是依赖集合中元素的equals()方法

Person类的内容

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    //比较两个人的姓名年龄
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Person person)) return false;
        return age == person.age && name.equals(person.name);
    }


    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class CollectionDemo03 {
    public static void main(String[] args) {
        //method01();
        Collection c = new ArrayList();
        Person p1 = new Person("乔峰", 30);
        Person p2 = new Person("阿朱", 20);
        c.add(p1);
        c.add(p2);

        Person p3 = new Person("乔峰", 30);

        System.out.println(c.remove(p3));
        System.out.println(c);
    }

    private static void method01() {
        Collection c = new ArrayList();
        c.add("abc");
        c.add("def");
        System.out.println(c);//[abc, def]

        System.out.println(c.remove("def"));//true

        System.out.println(c);//[abc]
        System.out.println(c.remove("gk"));//false
    }
}
     4.集合的迭代
        a.集合的迭代器相关的方法
           集合的通用迭代(遍历)方式:
                Iterator iterator()
                     从集合中获取一个迭代器对象,这个迭代器专门用来遍历集合中的元素

                Inerayor接口中的放啊:
                boolean hasNext()
                     判断集合中是否有遍历的元素,如果有,hasNext()就返回true,如果集合中没有要遍历的元素,就返回false
                Object next()
                     取出当前遍历的元素,并返回该元素

public class CollectionDemo01 {
    public static void main(String[] args) {
        //method01();
        //method02();
        Collection c = new ArrayList();
        c.add("李雷");
        c.add("韩梅梅");
        c.add("李宁");

        for (Iterator iterator = c.iterator(); iterator.hasNext();) {//没有步进表达式
            System.out.println(iterator.next());
        }


    }

    private static void method02() {
        Collection c = new ArrayList();
        c.add("李雷");
        c.add("韩梅梅");
        c.add("李宁");
        Iterator iterator = c.iterator();

       /*
        while(判断当前遍历元素是否存在){
            取出集合中的元素
        }
        */

        while (iterator.hasNext()) {//如果hasNext()返回true,代表当前待遍历的元素,如果返回false,没有要遍历的元素
            System.out.println(iterator.next());

        }
    }

    private static void method01() {
        Collection c = new ArrayList();
        c.add("李雷");
        c.add("韩梅梅");
        c.add("李宁");

        //1.获取一个迭代器对象
        Iterator iterator = c.iterator();//这个方法底层肯定是返回Iterator接口的实现类对象(多态)

        //2.调用hasNext()方法和next()方法
        System.out.println(iterator.hasNext());//true
        //集合中有待遍历的元素,:“李雷”,因此hasNext()返回true
        System.out.println(iterator.next());//李雷
        //取出当前的遍历元素,“李雷”
        System.out.println("------------");

        System.out.println(iterator.hasNext());//true
        //集合中有待遍历的元素,:“李雷”,因此hasNext()返回true
        System.out.println(iterator.next());//韩梅梅
        //取出当前的遍历元素,“韩梅梅”
        System.out.println("--------------");

        System.out.println(iterator.hasNext());//true
        System.out.println(iterator.next());//李宁

        System.out.println("--------------");
        System.out.println(iterator.hasNext());//false
        //此时集合中已经没有待遍历元素,所以hasNext()返回false
        // System.out.println(iterator.next());// java.util.NoSuchElementException  当前无元素异常
    }
}
        b.并发修改异常
           在使用迭代器遍历集合中容易引发的问题:
               需求:定义一个集合,向集合中添加三个字符串:”abc“ ,”def“,”ghk“
               当遍历到”ghk”的时候,删除该元素
               java.util.ConcurrentModificationException:并发修改异常
                  由于我们在使用迭代器的方法遍历的过程中,使用了集合的删除/添加 方法,导致并发修改异常
                  解决:
                     在使用迭代器遍历的过程中,如果需要增加/删元素,使用迭代器的方法来完成,就可以避免这个错误
                     void remove()
                     从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。

public class CollectionDemo02 {
    public static void main(String[] args) {
        //method01();

        Collection c = new ArrayList();
        c.add("abc");
        c.add("def");
        c.add("ghk");
        //1.获取一个迭代器对象
        Iterator iterator = c.iterator();
        //2.利用迭代器的判断和获取功能
        while (iterator.hasNext()) {
            Object ele = iterator.next();
            if (ele.equals("ghk")) {
                //c.remove(ele);
                iterator.remove();//删除当前迭代器遍历的元素,不用传参
                                  //[abc, def]
            }
        }
        //3.打印集合
        System.out.println(c);
    }

    //会引发并发修改异常
    private static void method01() {
        Collection c = new ArrayList();
        c.add("abc");
        c.add("def");
        c.add("ghk");
        //1.获取一个迭代器对象
        Iterator iterator = c.iterator();
        //2.利用迭代器的判断和获取功能
        while (iterator.hasNext()) {
            Object ele = iterator.next();
            if (ele.equals("ghk")) {
                c.remove(ele);
            }
        }
        //3.打印集合
        System.out.println(c);
    }
}
        c.增强for
           JDK1.5新特性:
               增强for:
                  用途:一般用来遍历数组和集合的
                      要求集合必须继承或实现Iterable接口
                  格式:
                     for(要遍历的容器中元素的类型 变量名 : 数组/集合){
                         //取出元素
                     }
           注意事项:
                1.使用增强for遍历集合其实底层使用的依然是迭代器
                  while(iterator.hashNext){
                    iterator.next();
                  }
                2.使用增强for遍历数组的时候,无法操作数组的索引

public class CollectionDemo03 {
    public static void main(String[] args) {
        int[] arr = {13, 17, 16, 21};
        //使用增强for
        //method01(arr);
        Collection c = new ArrayList();
        c.add(13);
        c.add("abc");
        c.add("ef");

        for (Object obj : c) {//每次将遍历的元素赋值给了obj变量
            System.out.println(obj);//第一次循环 取出第一个元素 obj = new Integer(13)
            //第二次循环 取出第二个元素 obj = new Integer("abc")
        }
        System.out.println("--------------");
        for (Object o : c) {
            System.out.println(o);
        }
    }

    private static void method01(int[] arr) {
        for (int ele : arr) {//每次将遍历的元素赋值给了ele变量
            System.out.println(ele);//第一次循环 取出第一个元素 ele = 13
            //第二次循环 取出第二个元素 ele = 17
        }

        for (int i : arr) {

        }
    }
}
     5.泛型
       a.类上的泛型
             类上的泛型当我们创建该类的对象的时候,类上的泛型被确定
                类名  引用变量名 = new 类名<指定类型>();

             类上的泛型:
                  格式:
                     class 类名<E,Q,A.....>{//泛型变量
                         一旦在类上定义泛型,类中均可以使用定义的泛型变量
                     }

                     如果不指定类型,那么这个泛型变量会被替换成Object类型


public class GenericDemo02<Q> {  //Q = String
    public void method(Q q) {//Q是泛型变量,
                             // q是变量名
        System.out.println(q);
    }

    public static void main(String[] args) {
        GenericDemo02<String> gd1 = new GenericDemo02<String>();//在申明对象的时候通过<>指定类型,这个类型必须是引用类型
                                                               //<String>相当于将String这个类型传递给了类上Q
                                                               //类上的泛型变量一旦有值,那么类上的所有用到Q的地方都会被替换成String
                                                               //method(Q,q) => method(String q)
        gd1.method("abc");//abc


        GenericDemo02<Integer> gd2 = new GenericDemo02<Integer>();//<Integer>相当于将Integer这个类型传递给了类上Q
                                                                  //类上的泛型变量一旦有值,那么类上的所有用到Q的地方都会被替换成Integer
                                                                  //method(Q,q) => method(Interger q)
        gd2.method(13);//13

        GenericDemo02 gd3 = new GenericDemo02();//如果不指定类型,那么这个泛型变量会被替换成Object类型
        gd3.method(1.524);


        //GenericDemo02<int> gd2 = new GenericDemo02<int>();
    }
}
       b.方法上的泛型
            当我们调用该方法传参的时候,方法上的泛型被确定
             方法上的泛型:
                 格式:
                    权限修饰符<T,Q,E....> 返回值类型 方法名(T t,Q q.....){  //<T,Q,E,....>方法上的泛型声明
                                                                       //可以在方法的形参以及方法内使用
                    }
/*
方法上的泛型:
    格式:
       权限修饰符<T,Q,E....> 返回值类型 方法名(T t,Q q.....){  //<T,Q,E,....>方法上的泛型声明
                                                          //可以在方法的形参以及方法内使用
       }
 */
public class GenericDemo01 {
    public <T> void method(T t) {
        System.out.println(t);
    }

    public static void main(String[] args) {
        GenericDemo01 gd = new GenericDemo01();
        gd.method("abc");//当我们传递字符串的时候,此时形参的T被替换为String类型
                            //替换为:method(String t)
        gd.method(12);  //当我们传递一个整数值的时候,此时形参的T被替换为int对应的包装类
                           //替换为:method(Integer t)

    }
}
/*
Collection接口中的toArray方法
       <T> T[] toArray(T[] a)
             将集合中元素存储到指定的数组中,然后返回装满了嘉禾中的元素的这个数组
 */
public class GenericDemo02 {
    public static void main(String[] args) {
        Collection<String> c = new ArrayList<String>();
        c.add("abc");
        c.add("def");
        c.add("ghk");
        String[] strs = new String[c.size()];
        String[] arr2 = c.toArray(strs);// <T> String[] toArray(String[] a)
                                           //由于我们这里传递的是String[](字符串数组类型),因此方法上的T就被替换成String
        //遍历arr数组
        for (String s : arr2) {
            System.out.println(s);
        }
    }
}
       c.接口上的泛型
             第一种方式:实现这个给接口的时候指定类型,从而确定接口上的泛型
             第二种方式:通过创建实现类对象来指定类型,确定类上的泛型,从而确定借口上的泛型
             接口上的泛型:
                 格式:
                     interface 接口名<T,E,Q.....>{  //接口上定义的泛型变量,都可以在接口中使用

                     }
/*
接口上的泛型:
    格式:
        interface 接口名<T,E,Q.....>{  //接口上定义的泛型变量,都可以在接口中使用

        }
 */
public interface Father <T>{
    void method(T t);
}
/*
当我们在定义类的时候实现父接口,位父接口传入类型
此时接口上的泛型变量会被替换为该类型,同时在接口中用到该泛型变量的位置都会被替换为该类型

 */
public class Son implements Father<String>{//String会被替换为接口上的T
                                           //而method方法上使用到了T也会被替换为String
    @Override
    public void method(String s) {
        System.out.println(s);
    }
}
public class Demo01 {
    public static void main(String[] args) {
        Son son = new Son();
        son.method("abc");
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值