Java学习-常用工具-集合

Java常用工具-集合

1. 集合简介

什么是集合?

简称集,是用来存储多个元素的容器

集合和数组的区别

  • 元素类型
        集合:引用类型(存储基本类型时自动装箱)
        数组:基本类型、引用类型
  • 元素个数
        集合:不固定,可任意扩容
        数组:固定,不能改变容量
  • 集合的好处
        不受容器大小限制,可以随时添加、删除元素
        提过了大量操作元素的方法(判断、获取等)

Java的集合体系

在这里插入图片描述

2. List集合的特点和应用

List集合的特点

在这里插入图片描述

案例:List集合的简单使用

在这里插入图片描述
代码演示

//学生类
public class Student {
    //成员变量
    private String name;
    private int age;

    public Student() {
    }

    public Student(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 String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
import java.util.ArrayList;
import java.util.List;

/*
    使用集合的步骤:
    1. 创建集合对象
    2. 创建元素对象
    3. 将元素对象添加到集合对象中
    4. 遍历集合
 */
public class Test {
    public static void main(String[] args) {
        //需求:往List集合中添加3个学生对象,然后遍历
        //1. 创建集合对象
        List list = new ArrayList();

        //2. 创建元素对象
        Student s1 = new Student("张三",41);
        Student s2 = new Student("张三",41);
        Student s3 = new Student("李四",42);
        Student s4 = new Student("王五",43);
        //3. 将元素对象添加到集合对象中
        list.add(s1);
        list.add(s2);
        list.add(s3);
        list.add(s4);

        //直接打印集合
        System.out.println(list);
        //获取索引为2的元素
        Object obj = list.get(2);
        System.out.println("索引为2的元素是:" + obj);

        //获取结合中元素个数
        System.out.println("集合的长度为:" + list.size());
        //4. 遍历集合
        for (int i = 0; i < list.size(); i++) {
            //i表示的就是集合中每个元素的索引
            //获取元素
            Object obj2 = list.get(i);
            System.out.println("索引为:" + i + "的元素是:" + obj2);
        }

    }
}

运行结果
在这里插入图片描述

3. 增强for循环和迭代器

为什么需要增强for循环?

简化数组和集合的遍历

  • 增强for循环的格式:
        for(数据类型 变量名 : 数组或者集合对象) {
          //循环体,变量即元素
        }

代码演示

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

/*
    快捷方式 iter + enter
    注意:
        增强for的底层依赖的是迭代器(Iterator)
        大白话解释:增强for就是迭代器的间歇形式
 */
public class Test {
    public static void main(String[] args) {
        //需求:通过增强for遍历List集合
        //1. 创建集合对象
        List list = new ArrayList();
        //2. 创建元素对象

        //3. 将元素对象添加到集合中
        list.add(10);
        list.add(10);
        list.add(30);
        list.add(20);
        list.add(40);

        //4. 遍历集合
        for (Object obj : list) {
            //obj是集合中的元素,其本身应该是Integer类型的数据
            Integer i1 = (Integer)obj;
            System.out.println(i1);
        }
        System.out.println("-----------------");

        for (Object obj : list) {
            Integer i1 = (Integer)obj;
            System.out.println(i1);
        }
    }
}

运行结果
在这里插入图片描述

为什么需要迭代器?

对过程的重复,称为迭代。
迭代器是变量Collection集合的通用方式,可以在对集合遍历的同时进行添加、删除等操作。

迭代器的常用方法

  • next():返回迭代的下一个元素对象
  • hasNext():如果仍有元素可以迭代,则返回true
Demo1

代码演示

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

/*
    注意:
        列表迭代器是List体系独有的遍历方式,可以在对集合遍历的同时进行添加、删除等操作
        但是必须通过调用列表迭代器的方法来实现

    使用步骤:
        1. 根据集合对象获取其对象的迭代器对象。
        2. 判断迭代器中是否有元素
        3. 如果有就获取元素
    总结:
        普通的迭代器在遍历集合的同时不能添加或者删除元素,否则会报:并发修改异常
        列表迭代器在遍历集合的同时可以修改集合中的元素(添加,删除等),必须使用列表迭代器中的方法

 */
public class Test {
    public static void main(String[] args) {
        //需求:通过迭代器遍历List集合
        //1. 创建集合对象
        List list = new ArrayList();
        //2. 创建元素对象
        //3. 将元素对象添加到集合当中
        list.add("a");
        list.add("b");
        list.add("c");
        //4. 遍历集合
        //迭代器的用法
        //1. 根据集合对象获取其对象的迭代器对象。
        /*Iterator it = list.iterator();
        //2. 判断迭代器中是否有元素
        while (it.hasNext()) {  //如果迭代器中有元素,就一直迭代
            //3. 如果有就获取元素
            String s = (String)it.next();
            System.out.println(s);
        }*/

        System.out.println("---------------------");

        //需求:判断集合中如果有字符串"b",就在其后边添加一个新的字符串:java
        Iterator it = list.iterator();
        //2. 判断迭代器中是否有元素
        while (it.hasNext()) {  //如果迭代器中有元素,就一直迭代
            //3. 如果有就获取元素
            String s = (String)it.next();
            if ("b".equals(s)) {    //这样写可以规避空指针异常,"b"是常量
                //能走到这里,说明集合中有元素b
                list.add("java");   //这样写不行,会报ConcurrentModificationException(并发修改异常)
            }
            System.out.println(s);
        }

    }
}

运行结果
在这里插入图片描述

Demo2

代码演示

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

public class Test1 {
    public static void main(String[] args) {
        //需求:测试列表迭代器
        //1. 创建集合对象
        List list = new ArrayList();
        //2. 创建元素对象
        //3. 将元素对象添加到集合当中
        list.add("a");
        list.add("b");
        list.add("c");
        //需求:判断集合中如果有字符串"b",就在其后边添加一个新的字符串:java
        //1. 根据集合对象获取列表迭代器对象
        ListIterator lit = list.listIterator();
        //2. 判断迭代器中是否有元素
        while (lit.hasNext()) {
            //3. 有就获取元素即可
            String s = (String)lit.next();
            if ("b".equals(s)) {
                //list.add("java");   这样写不行,必须调用列表迭代器的方法来实现.
                lit.add("java");
            }
            System.out.println(s);
        }
        System.out.println("-------------");
        //打印新的集合中的值
        System.out.println(list);
    }
}

运行结果
在这里插入图片描述

4. 泛型简介

什么是泛型?

即泛指任意类型,又叫参数化类型(ParameterizedType),
对具体类型的使用起到辅助作用,类似于方法的参数。

集合类泛型的解释

表示该集合中存放指定类型的元素

  • 案例演示(给List集合加上泛型String)
      List list = new ArrayList<>();
  • 泛型的好处
      类型安全
      避免了类型转换

代码演示

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

/*
    总结:
        泛型一般只和集合类相结合使用
        泛型JDK5的新特性,但从JDK7开始,后边的泛型可以不用写具体的数据类型了(菱形泛型)
 */
public class Test {
    public static void main(String[] args) {
        //不使用泛型的集合
        //1. 创建集合对象
        List list = new ArrayList();
        //2. 创建元素对象
        //3. 将元素对象添加到集合对象中
        list.add("a");
        list.add("b");
        list.add("c");
        //list.add(10);   会报类型转换异常(ClassCastException)

        //4. 遍历集合
        for (Object obj : list) {
            String s = (String)obj;
            System.out.println(s);
        }
        System.out.println("-----------------");

        //需求:演示泛型
        //1. 创建集合对象
        List<String> list2 = new ArrayList<>();
        //2. 创建元素对象
        //3. 将元素对象添加到集合对象中
        list2.add("abc");
        list2.add("bcd");
        list2.add("cde");

        //4. 遍历集合
        for (String s : list2) {
            System.out.println(s);
        }

    }
}

运行结果
在这里插入图片描述

5. Collections工具类

Collections简介

针对集合进行操作的工具类

成员方法

在这里插入图片描述
代码演示

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        //创建集合对象
        List<Integer> list = new ArrayList<>();
        //往集合中添加数据
        list.add(1);
        list.add(3);
        list.add(3);
        list.add(5);
        list.add(2);
        list.add(2);
        list.add(4);

        //打印集合
        System.out.println("没有操作以前,集合中的数据是:" + list);
        System.out.println("-----------------");

        //获取集合中最大元素
        Integer max = Collections.max(list);
        System.out.println("集合中的最大元素为:" + max);
        System.out.println("-----------------");

        //对集合进行升序排列
        Collections.sort(list);
        System.out.println("升序排列后的结果为:" + list);
        System.out.println("-----------------");

        //对集合中的数据进行反转
        Collections.reverse(list);
        System.out.println("反转以后集合中的数据为:" + list);

        //需求:对集合中的数据进行降序排列
        //先对集合中的数据进行:升序排列
        Collections.sort(list);
        //然后反转集合中的数据
        Collections.reverse(list);
        System.out.println("降序后的结果为:" + list);
        System.out.println("-----------------");

        //随机置换,相当于洗牌
        Collections.shuffle(list);
        System.out.println("随机置换后的结果为:" + list);
    }
}

运行结果
在这里插入图片描述

6. Set集合的特点

Set集合的特点

  • 特点
      不可重复、无序
  • 应用
      Set <T> set = new HashSet<>();

案例:Set集合的简单使用

在这里插入图片描述
代码演示

import java.util.Objects;

public class Student {
    //成员变量
    private String name;
    private int age;

    public Student() {
    }

    public Student(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 String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/*
    结论:
        Set集合保证元素的唯一性依赖:equals(),hashCode()两个方法。
 */
public class Test {
    public static void main(String[] args) {
        //需求:往set集合中添加5个学生对象,然后遍历
        //1. 创建集合对象
        Set<Student> set = new HashSet<>();
        //2. 创建元素对象

        Student s1 = new Student("张三", 41);
        Student s2 = new Student("李四", 42);
        Student s3 = new Student("王五", 43);
        Student s4 = new Student("张三", 41);
        Student s5 = new Student("李四", 42);
        //3. 将集合对象添加到元素对象中
        set.add(s1);
        set.add(s2);
        set.add(s3);
        set.add(s4);
        set.add(s5);
        //4. 遍历集合
        /*
            为什么Set集合没有“去重”?
                因为Set集合宝恒元素的唯一性依赖:equals() 和 hashCode()两个方法
                你没有在Student类中重写这两个方法,默认调用的是Object类中的这两个方法
                而Object类中的equals()方法默认比较的是地址值是否相同

            解决方案:
                在Student类中重写equals()和hashCode()方法
         */
        System.out.println(set);
        System.out.println("-------------");

        System.out.println("通过迭代器实现");
        //通过迭代器遍历Set集合
        //A. 通过集合对象获取其对应的迭代器对象
        Iterator<Student> it = set.iterator();
        //B. 判断迭代器中是否有元素
        while (it.hasNext()) {
            //C. 如果有,就获取元素
            Student s = it.next();
            System.out.println(s);
        }
        System.out.println("-------------");

        //通过增强for遍历Set集合
        System.out.println("通过增强for遍历Set集合");
        for (Student student : set) {
            System.out.println(student);
        }

    }
}

运行结果
在这里插入图片描述

7. Map集合的特点和应用

Map集合的特点

  • 特点
      双列集合,元素由键值对(Entry)构成:
        key – value
      key不可以重复,value可以重复
  • 应用
    Map<T1,T2> map = new HashMap<>();

案例:Map集合的简单使用

在这里插入图片描述
5.通过key分别获取对应的value并打印
代码演示

import java.util.Objects;

//学生类
public class Student {
    //成员变量
    private String name;
    private int age;

    public Student() {
    }

    public Student(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 == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/*
    遍历步骤:
        1. 获取所有键的集合         keySet()
        2.遍历所有的键,获取到每一个键,       迭代器,增强for
        3. 根据键获取指定的值        get()
 */
public class Test {
    public static void main(String[] args) {
        //需求:往Map集合中添加3个学生对象,然后打印
        //1. 创建集合对象
        //键:学生的编号   值:具体的学生对象
        Map<Integer,Student> map = new HashMap<>();
        //2. 创建元素对象
        Student s1 = new Student("张三",23);
        Student s2 = new Student("李四",24);
        Student s3 = new Student("张三",23);

        //3. 将元素对象添加到集合对象中
        //put() 元素第一次添加,返回null,重复添加,会用新值覆盖旧值,并返回旧值
        /*Student stu1 = map.put(1,s1);
        System.out.println("stu1:" + stu1);
        Student stu2 = map.put(1,s2);
        System.out.println("stu2:" + stu2);*/
        map.put(1,s1);
        map.put(2,s2);
        map.put(3,s3);

        //根据键,获取值
        Student stu3 = map.get(2);
        System.out.println("key:" + 2 + ",value:" + stu3);
        //打印集合
        System.out.println(map);
        System.out.println("--------------------");

        //4. 遍历集合
        /*//4.1. 获取所有键的集合         keySet()
        Set<Integer> keys = map.keySet();
        //4.2.遍历所有的键,获取到每一个键,       迭代器,增强for
        Iterator<Integer> it = keys.iterator();
        while (it.hasNext()) {
            //如果迭代中有数据,就获取
            Integer key = it.next();
            //4.3. 根据键获取指定的值        get()
            Student value = map.get(key);
            System.out.println("key:" + key + ",value:" + value);
        }*/

        //通过增强for实现
        //获取到所有的键
        Set<Integer> keys = map.keySet();
        for (Integer key : keys) {
            //key就是双列结合中的每一个键
            Student value = map.get(key);
            System.out.println("key:" + key + ",value:" + value);
        }
    }
}

运行结果
在这里插入图片描述

8. 案例:模拟斗地主发牌功能

在这里插入图片描述

import java.util.*;

public class SendPokerTest {
    public static void main(String[] args) {
        //1. 买牌
        //1.1 定义一个双列集合,键:表示键的编号,值:表示具体的牌 规则:编号越小,牌越小
        Map<Integer, String> pokers = new HashMap<>();
        //1.2 定义一个单列集合,用来存储所有牌的编号
        List<Integer> list = new ArrayList<>();
        //1.3具体的买牌动作
        //普通牌,52
        String[] colors = {"♠","♥","♣","♦"};
        String[] numbers = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
        int num = 0;
        //通过循环嵌套,造 普通牌
        for (String number : numbers) {     //外循环,获取所有的点数
            for (String color : colors) {      //内循环,获取所有的花色
                String poker = color + number;
                //System.out.println(poker);
                //将牌的编号,具体的牌放到双列集合中
                pokers.put(num, poker);
                //将牌的编号放到单列集合中
                list.add(num);
                //每添加一张牌,编号要自增1
                num++;
            }
        }
        //大小王
        //添加小王
        pokers.put(num,"小王");
        list.add(num++);
        //添加大王
        pokers.put(num,"大王");
        list.add(num);

        //打印牌
        System.out.println("所有牌:" + pokers);
        System.out.println("牌的编号" + list);

        //2. 洗牌
        Collections.shuffle(list);
        System.out.println("洗好牌后,编号为:" + list);

        //3. 发牌
        //3.1 定义4个集合,分别表示3个玩家,底牌.
        List<Integer> Jake = new ArrayList<>();
        List<Integer> Jennie = new ArrayList<>();
        List<Integer> Lisa = new ArrayList<>();
        List<Integer> dipai = new ArrayList<>();

        //3.2 具体的发牌动作,将索引和3取模,决定发给谁
        for (int i = 0; i < list.size(); i++) {
            //获取编号
            Integer pokerNum = list.get(i);
            //System.out.println(pokerNum);
            if (i >= list.size() - 3) {
                //底牌
                dipai.add(pokerNum);
            } else if (i % 3 == 0) {
                Jake.add(pokerNum);
            } else if (i % 3 == 1) {
                Jennie.add(pokerNum);
            } else if (i % 3 == 2) {
                Lisa.add(pokerNum);
            }
        }
        //3.3 查看玩家,底牌的编号
        /*System.out.println("Jake:" + Jake);
        System.out.println("Jennie:" + Jennie);
        System.out.println("Lisa:" + Lisa);
        System.out.println("底牌:" + dipai);*/

        //4. 查看具体的牌
        System.out.println("----------------------");
        /*String str = printPoker(Jake, pokers);
        System.out.println("Jake:" + str);*/
        System.out.println("Jake:" + printPoker(Jake, pokers));
        System.out.println("Jennie:" + printPoker(Jennie, pokers));
        System.out.println("Lisa:" + printPoker(Lisa, pokers));
        System.out.println("底牌:" + printPoker(dipai, pokers));

    }
    /*
            4. 定义一个方法,用来看牌
                方法名:printPoker
                参数列表:List<Integer>, Map<Integer, String>
                返回值:String
         */
    public static String printPoker(List<Integer> nums, Map<Integer,String> pokers) {
        //1. 对牌的编号进行升序排列
        Collections.sort(nums);
        //2. 遍历牌的编号集合,获取到每一个编号
        StringBuilder sb = new StringBuilder();
        for (Integer num : nums) {
            // num就是要查找的具体牌的 编号
            //3. 根据编号去双列集合中查找该编号对应的具体牌
            String poker = pokers.get(num);
            //4. 将获取到的牌进行拼接
            sb.append(poker + " ");
        }
        //5. 将最后拼接结果返回即可
        String str = sb.toString();
        return str.trim();
    }
}

运行结果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值