JavaSE笔记_day13_List

172 阅读14分钟

一.集合的概述

1.数组和集合的区别

  • 1.数组是定长容器,int[] arr = new int[3]; 

       集合是可变长度容器,集合底层也是一个数组,初始开辟一个指定大小的数组,然后向数组中添加数据,如果数据将数组添加满了, 系统底层默认的分配一个更大的数组空间,原数组中内容复制到新数组中,继续向新数组中添加内容。

  • 2.数组可以存储基本数据类型 double[] d = new double[5];、数组可以存储引用数据类型 String[] s = new String[3]; 

       集合只能存储引用数据类型 如果客户的年龄为int类型,要存储在集合中,实际存储在集合中的基本数据类型对应的引用数据类型包装类 

  • 3.数组中的方法只能使用Object中继承来的方法,有一个属性length 

       集合是一个类,既可以使用Object中继承方法,类中自己封装了很多的方法

2.集合的体系结构


单列集合:容器中每一个元素,都是一个独立的个体。
(接口:所有单列集合的顶层父接口)
Collection —— List:接口、有序、有索引、可重复
                    —— ArrayList:底层数组结构、查询快、增删慢
                    —— LinkList:底层链表结构、查询慢、增删快
                    —— Vector:底层数组结构、查询慢、增删慢 
           ——  Set:接口、无序、无索引、不重复
                    —— HashSet:底层数组+链表、查询快、增删快

双列集合:容器中一对元素,是一个整体
(接口:所有双列集合的父接口)
Map —— HashMap:

二.Collection集合

1.Collection集合的介绍

  • Collection是一个接口,所有单列集合的顶层父接口,来自于java.util包 
  • Collection兼容子接口List、Set的共有方法 
  • Collection是接口,不能实例化对象,需要找一个实现类,ArrayList 
  • Collection coll = new ArrayList();//接口的多态性,父类引用指向子类对象,左接口右实现类 
       coll调用的方法全部都是ArrayList中的重写方法。

2.Collection集合的常用方法

1.add(Object a):向集合末尾添加一个元素obj
2.remove(Object obj): 将obj元素从集合中删除,返回值类型Boolean类型。删除成功True、删除失败false
3.clear():清空集合,将集合中的数据删除,集合仍然存在。返回值类型void。
4.isEmpty:判断集合是否为空。返回值类型Boolean,空集合返回true,否则false。
5.contains(Object obj):判断obj元素在集合中是否存在,返回值类型Boolean,存在返回true,否则返回false

import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo {
    public static void main(String[] args) {
        addMethod();
        removeMethod();
        clearMethod();
        containsMethod();
    }
    public static void addMethod(){
        //1.创建一个集合,多态写法
        Collection coll1 = new ArrayList();
       
     //2.add(Object obj)
        coll1.add("abc");
        coll1.add("123");
        //String重写了父类Object中toString方法,将集合中的元素打印出来
        System.out.println(coll1);//[abc, 123]

        Collection coll2 = new ArrayList();
        Student s = new Student("张三",20);
        coll2.add(s);
        coll2.add(new Student("李四",20));
        System.out.println(coll2);
        //[com.bjzhang.demo01.Student@10f87f48, com.bjzhang.demo01.Student@b4c966a]
        //Student需要重写ArrayList中toString方法 [Student{name='张三', age=20}, Student{name='李四', age=20}]
    }
    public static void removeMethod(){
        //1.创建一个集合
        Collection coll3 = new ArrayList();
        //自动装箱,将int类型数据12自动封装成Integer类型
        coll3.add(12);
        coll3.add(-7);
        coll3.add(25);
        System.out.println(coll3);//[12, -7, 25]
       
     //2.remove(Object obj)
        coll3.remove(-7);
        System.out.println(coll3);//[12, 25]
    }
    public static void clearMethod(){
        //1.创建一个集合
        Collection coll4 = new ArrayList();
        //自动装箱,将int类型的数据自动封装成integer类型
        coll4.add(12);
        coll4.add(-7);
        coll4.add(25);
        System.out.println(coll4);//[12, -7, 25]

        //2.clear()
        coll4.clear();
        System.out.println(coll4);//[]

        //3.isEmpty()
        System.out.println(coll4.isEmpty());//true
    }
    public static void containsMethod(){
        //1.创建一个集合
        Collection coll5 = new ArrayList();

        //2.add(Object obj)
        coll5.add("123");
        coll5.add("abs");

        System.out.println(coll5.contains("12"));//false
        System.out.println(coll5.contains("123"));//true
    }
}				
public class Student {
    private String name;
    private int 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;
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public Student() {
    }
    @Override
    public String toString() {
        return "Student{" +
	    "name='" + name + '\'' +
	    ", age=" + age +
	    '}';
        }
}

3.Collection集合中带有all的方法  — 返回值类型Boolean

1.A.addAll(Collection c):将集合c的全部内容,追加到集合A末尾中。
2.A.containsAll(Collection c):判断集合A中,是否包含集合C。
3.A.removeAll(Collection c):删除集合A和集合c在A中共有的元素。
4.A.retainAll(Collection c):将集合A和集合c的交集赋值给A集合。

import java.util.ArrayList;
import java.util.Collection;
public class CollectionAllMethod {
    public static void main(String[] args) {
        //1.A.addAll(Collection c):将集合c的全部内容,追加到集合A末尾中。
        Collection coll1 = new ArrayList();
        coll1.add("a");
        coll1.add("b");
        Collection coll2 = new ArrayList();
        coll2.add("c");
        coll2.add("d");
        coll1.addAll(coll2);
        System.out.println(coll1);//[a, b, c, d]
					
        //2.A.containsAll(Collection c):判断集合A中,是否包含集合C。
        System.out.println(coll1.containsAll(coll2));//true
					
        //3.A.removeAll(Collection c):删除集合A和集合的交集在A中共有的元素。
        Collection coll3 = new ArrayList();
        coll3.add(1);
        coll3.add(2);
        Collection coll4 = new ArrayList();
        coll4.add(1);
        coll3.removeAll(coll4);//删除coll3和coll4在coll3中共有的元素
        System.out.println(coll3);//[2]
					
        //4.A.retainAll(Collection c):将集合A和集合c的交集赋值给A集合。
        Collection coll5 = new ArrayList();
        coll5.add(1);
        coll5.add(2);
        Collection coll6 = new ArrayList();
        coll6.add(3);
        coll6.add(4);
        coll5.retainAll(coll6);
        System.out.println(coll5);//[]

        Collection coll7 = new ArrayList();
        coll7.add(1);
        coll7.add(4);
        coll6.retainAll(coll7);
        System.out.println(coll6);//[4]
    }
}

4.Collection集合的第一种遍历形式

  • toArray():将集合中的所有的元素,以一个Object[]形式进行返回,返回值类型Object[] 
  • 为什么方法的返回值类型是Object[]?
       因为集合容器中可以存储任意的引用数据,将一个父类作为所有子类的代表进行返回

5.Collection集合的第二种遍历形式 - 迭代器

迭代:表示从一个到下一个的过程。
迭代器:作用就是将集合中的元素,一个一个的获取到
1.iterator():获取集合的迭代器对象,返回值类型iterator,不能实例化对象 
    iterator 表示一个迭代器,接口,来自于java.util包
    iterator 不能实例化对象,那么证明iterator()方法实际返回的接口是一个实现类对象
2.迭代器中的方法
    hasNext(): 判断集合中是否有下一个元素,返回值类型Boolean类型,如果有返回true,否则返回false 
    next():获取当前正在迭代的元素本身,返回值类型Object类型
    注意:如果集合中已经没有元素需要获取,继续使用next进行集合中元素获取,报错。没有这个元素异常,java.util.NoSuchElementException
3.迭代器的工作原理
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionIterator {
    public static void main(String[] args) {
        //1.创建一个集合
        Collection c = new ArrayList();
        c.add("a");
        c.add("b");
        c.add("c");
        c.add("d");
        //2.使用迭代器的方式获取集合中的元素
        //(1)先获取集合的迭代器对象
        Iterator it = c.iterator();//多态,左接口右实现类
        while(it.hasNext()){
            System.out.println(it.next());//a.b.c.d
        }
    }
}

三.List集合

1.List集合的概述

  • List 接口,来自于java.util包,是Collection的子接口
  • List 接口,不能实例化对象(new 对象),找实现类 ArrayList 
  • List list = new ArrayList();//多态,左接口右实现类
  • List接口特征:
  1. 有序:元素存入集合顺序与取出顺序一致 
  2. 有索引:索引范围0--集合的长度-1 
  3. 可重复:集合中允许存储重复元素

2.List集合的特有方法

add(int i , Object obj):将obj元素添加到集合指定i位置上,其他元素后移
remove(int i):删除索引为i的元素,返回值类型Object,返回所删元素
set(int i , Object obj): 将obj元素与索引i替换,返回值类型Object,返回被替换元素
get(int i):获取i索引位置上的元素

import java.util.ArrayList;
import java.util.List;
public class ListMethod {
    public static void main(String[] args) {
        addMethod();
        removeMethod();
        setMethod();
        getMethod();
    }
    public static void addMethod(){
        //1. 创建一个集合
        List li = new ArrayList();
        //2.add(int i , Object obj)
        li.add(0,"a");
        li.add(0,"b");
        System.out.println(li);//[b, a]
        li.add("c");
        li.add("d");//[b,a,c,d]
        li.add(2,"hello");
        System.out.println(li);//[b,a,hello,c,d]
    }
    public static void removeMethod(){
        //1. 创建一个集合
        List li = new ArrayList();
        //2.add(int i , Object obj)
        li.add(0,"a");
        li.add(0,"b");
        System.out.println(li);//[b, a]
        li.add("c");
        li.add("d");//[b,a,c,d]
        li.add(2,"hello");

        //3.remove(int i):删除指定索引的元素
        String s = (String)li.remove(3);
        System.out.println(li);//[b, a, hello, d]
        System.out.println(s);//c
    }
    public static void setMethod(){
        List list = new ArrayList();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        Object obj = list.set(2,"QQ");
        System.out.println(obj);//c
        System.out.println(list);//[a, b, QQ, d]
    }
    public static void getMethod(){
        List list = new ArrayList();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        Object obj = list.get(0);//a
        System.out.println(obj);
        System.out.println(list.get(2));//c
        //System.out.println(list.get(5));//下标索引越界异常 java.lang.IndexOutOfBoundsException
    }
}

3.List集合的遍历

1.List集合可以使用迭代器遍历,
2.List可以根据索引进行遍历,索引范围0-集合长度-1,get(int index)
3.求集合长度的方法 size(),返回值类型int类型 
    (1)数组求长度 length 属性
    (2)字符串长度 length()方法
    (3)集合的长度获取 size() 方法 

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

public class ListFor {
    public static void main(String[] args) {
        //1.创建一个集合
        List list = new ArrayList();
        list.add(1);
        list.add(2);
        list.add(4);
        //2.求取集合的长度
        int len = list.size();
        System.out.println(len);//4
        //3.list集合的遍历
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));//1.2.3.4
        }
        //4.迭代器遍历
        Iterator it = list.iterator();
        while(it.hasNext()){
            System.out.println("--"+it.next());
        }
    }
}

4.并发修改异常

需求:集合["a","hello","b"],遍历集合,如果遇到集合中的元素为"hello",那么向集合中添加一个元素"world"
使用迭代器方式实现
    -- ConcurrentModificationException:并发修改异常
出现异常的原因:当通过迭代器进行集合的遍历的时候,一边遍历,一边向集合中添加元素。迭代器就会爆出,并发修改异常。
对策:
    for循环进行集合的遍历
    ListIterator//一边遍历,一边循环

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

public class ListException {
    public static void main(String[] args) {
        //addEle();
        //forEle();
        listIteratorMethod();
    }
    public static void addEle(){
        List list = new ArrayList();
        list.add("a");
        list.add("hello");
        list.add("b");
        System.out.println(list);
        //使用迭代器遍历
        //(1)获取到集合的迭代器对象
        Iterator it = list.iterator();
        while(it.hasNext()){
            Object obj = it.next();
            String s = (String)obj;
            if("hello".equals(s)){
                list.add("world");
            }
        }
        System.out.println(list);//[a, hello, b]
    }
    public static void forEle(){
        List list = new ArrayList();
        list.add("a");
        list.add("hello");
        list.add("b");
        System.out.println(list);
        for (int i = 0 ; i < list.size() ; i++){//每次循环都会调用list.size(),如果集合大小改变,list.size()跟着判断
            if("hello".equals((String)list.get(i)))
                list.add("world");
            }
            System.out.println(list);//[a, hello, b, world]
        }
    public static void listIteratorMethod(){
        List list = new ArrayList();
        list.add("a");
        list.add("hello");
    	list.add("b");
    	System.out.println(list);
        ListIterator it = list.listIterator();
        while(it.hasNext()){
            Object obj = it.next();
            String s = (String)obj;
            if("hello".equals(s))
                //list.add("world");
                it.add("world");//通过迭代器添加
        }
        System.out.println(list);//[a, hello, world, b]
    }
}		

5.List的实现类

子类具有父类(接口)中所有的方法
    ArrayList:底层数组结构、查询快、增删慢
    LinkedList:底层是链表结构,查询慢,增删快
    Vector:底层数组结构、查询慢、增删慢 从jdk1.2版本,被ArrayList取代
    ArrayList数组结构
        数组已满,添加元素,末尾追加
        原数组元素已经装满,系统重新创建一个更大的数组,将原数组内容复制到新数组中,然后再向新数组中添加元素。
        增加跟删除慢
        查找快(索引)
    LinkedList链表结构
        查询慢,每个元素必须查询到,牵手式
        增删快,只需要改变指针指向即可

练习1:分析以下需求,并用代码实现
    (1)生成10个1-100之间的随机整数,存入一个List集合 --> 解决去重问题
    (2)编写方法对List集合进行排序(由大到小)
    (3)然后利用迭代器遍历集合元素并输出
    (4)如,15 18 20 40 46 65 70 75 91

import java.util.*;
public class HomeWork1 {
    public static void main(String[] args) {
        //1.创建随机数对象
        Random r = new Random();
        //2.创建一个集合list,装10个不重复的随机数
        ArrayList<Integer> list = new ArrayList();
        //3.创建一个集合list100,装1-100的整数,用于挑选不重复的随机数
        ArrayList<Integer> list100 = new ArrayList();
        for(int i = 1 ; i <= 100 ; i++){
            list100.add(i);
        }
        //4.将10个随机的不重复数,放到list集合中
        for(int i = 0 ; i < 10 ; i++){
            //生成1-100的随机数
            int count = r.nextInt(100)+1;
            int result = list100.get(count - 1);//生成随机数1对应list100(0)
            if(result != 0){//这个随机数没有被挑选过
                list.add(count);
                list100.set(count-1,0);//将刚刚挑选过的置为0
            }else{//这个随机数被挑选过
                i--;
            }
        }    
	/*Collections.sort(list);
	System.out.println(list);//[10, 18, 21, 33, 40, 41, 64, 81, 83, 95]
	*/
	//5.利用数组中选择排序法
	up(list);
//      System.out.println(list);//[2, 11, 15, 25, 26, 28, 45, 54, 59, 63]

        //6.使用迭代器遍历list集合
        Iterator<Integer> it = list.iterator();
        while(it.hasNext()){
            System.out.print(it.next()+" " );//7 14 34 37 40 54 67 75 79 95
        }
    }
    public static void up(ArrayList<Integer> list){
        //5.利用数组中选择排序法
        for(int i = 0 ; i < list.size() ; i++ ){//0索引元素和后面所有元素比较
            for(int j = i + 1 ; j < list.size() ; j++){
                if(list.get(i) > list.get(j)){
		    int temp = list.get(i);
		    list.set(i,list.get(j));//list中第i个索引替换为后面
		    list.set(j,temp);
	        }
	    }
        }
    }
}

练习2:分析以下需求,并用代码实现
    (1)定义List集合,存入多个字符串,其中包含三个连续的"def"
    (2)删除集合中字符串"def"
    (3)然后利用迭代器遍历集合元素并输出 

import java.util.*;
public class HomeWork2 {
    public static void main(String[] args) {
        //1.创建一个list集合,存放String类型的字符串
        ArrayList<String> list = new ArrayList<>();
        //2.向集合中添加字符串,包含三个连续的"def"
        list.add("abc");
        list.add("a");
        list.add("def");
        list.add("def");
        list.add("def");
        list.add("hello");
        list.add("123");
        list.add("QQ");
        System.out.println(list);//[abc, a, def, def, def, hello, 123, QQ]
        //3.Collections接口,带有ALL方法,A.removeAll(Collection c) 删除A集合和c集合在A中共有的元素
        ArrayList<String> listDef = new ArrayList<>();
        listDef.add("def");
        list.removeAll(listDef);
        System.out.println(list);//[abc, a, hello, 123, QQ]
    }
}

练习3.分析以下需求,并用代码实现
    (1)定义List集合,存入多个字符串 
    (2)删除集合中包含0-9数字的字符串(只要字符串包含)
    (3)然后利用迭代器遍历集合元素并输出 

import java.util.ArrayList;
import java.util.Iterator;
public class HomeWork3 {
    public static void main(String[] args) {
        //1.创建一个List集合
        ArrayList<String> list = new ArrayList<>();
        //2.向集合中添加元素
        list.add("1abc");
        list.add("he7llo");
        list.add("world12");
        list.add("799");
        list.add("ef");
        //3.remove():表示在迭代过程中,将目前正在迭代的元素进行删除,不会发生并发修改异常
        Iterator<String> it = list.iterator();
        while(it.hasNext()){
            String s = it.next();
            //判断字符串中是否包含数字
            //正则表达式[^0-9]{1,}    -->   匹配没有数字的字符串
            if(!s.matches("[^0-9]{1,}")){//字符串中包含数字
                it.remove();
            }
        }
        System.out.println(list);//[ef]
    }
}

练习4.定义一个方法:给定一个数组,将数组内容转换成一个字符串
    例如:数组为int[] arr = {1,2,3},输出字符串为[1,2,3]
    本题使用StringBuilder拼接字符串实现

public class HomeWork4 {
    public static void main(String[] args) {
        int [] arr = {-23,99,56,7};
        try{
            System.out.println(function(arr));//2.int [] arr = {}; []
                                              //3.int [] arr = {-23,99,56,7}; [-23,99,56,7]
	}catch(Exception ex){
	    ex.printStackTrace();//1.int [] arr = null; java.lang.Exception: 数组不能为null
        }
    }
    public static String function(int[] arr) throws Exception{
        //1.arr数组不能为null
        if(arr == null){
            throw new Exception("数组不能为null");//编译异常一旦出现必须声明或处理
        }
        //2.arr数组如果没有元素,是一个空数组[]
        if(arr.length == 0){
            return "[]";
        }else{//3.数组中有元素
            //需要将arr数组中每一个元素都获取到
            StringBuilder sb = new StringBuilder("[");
            for(int i = 0 ; i < arr.length ; i++){
                if(i==arr.length-1){
		    //最后一个元素需要拼接]
	            sb.append(arr[i]+"]");
	        }else {//除最后元素,其他元素后拼接逗号
		    sb.append(arr[i] + ",");
                }
            }
            return sb.toString();
        }
    }
}

练习5.分析以下需求,并用代码实现
    (1)定义数字字符串数组{"010","3223","666","7890987","123123"}
    (2)判断该数字字符串数组中数字字符串是否对称
    (3)打印该数组中对称字符串的个数

分析:
    1.将字符串中的每一个字符获取到
    2.7890987 需要两个索引,比较对应索引位置
public class HomeWork5 {
    public static void main(String[] args) {
        //1.创建一个字符串数组
        String[] ss = {"010","3223","666","7890987","123123"};
        //2.获取每一字符串
        for(String ele : ss){
            //3.将获取到的字符串中的每一个字符获取到
            char[] ch = ele.toCharArray();
	    //4.判断ch数组中存储的元素是否对称存在
	    //设定标志,默认值为TRUE
	    boolean flag = true;
	    for(int i = 0,j = ch.length-1 ; i < j ; i++,j--){
	        if(ch[i]!=ch[j]){
	            flag = false;
	            break;
		}
	    }
            if(flag == true){
                System.out.print(ele+"  ");//010  3223  666  7890987  
            }
        }
    }
}

练习6.编写Person类,类中具有姓名,年龄,性别,地址
    属性值如下列表,将每个人的信息放入集合中,遍历集合,在main函数中输出每个人的信息
        姓名	年龄	性别	地址
        张三	 23·	男	河南
        李四	 45 	男 	河南
        王五	 34   	女	山西
        赵六	 22 	男	北京
        田七	 33 	女	北京

import java.util.ArrayList;
public class HomeWork6 {
    public static void main(String[] args) {
        //1.先创建一个存储Person对象的集合
        ArrayList<Person> list = new ArrayList<>();
        //2.向集合中添加Person对象
        list.add(new Person("张三",23,"男","河南"));
	list.add(new Person("李四",45,"男","河南"));
	list.add(new Person("王五",34,"女","山西"));
	list.add(new Person("赵六",22 ,"男","上海"));
	list.add(new Person("田七",33,"女","北京"));
	//增强for遍历list
	for(Person p:list){
	    System.out.println(p.getName()+"--"+p.getAge()+"--"+p.getSex()+"--"+p.getAddr());
	}
    }
}