Java集合超详解一文带你玩转集合

什么是集合?

1.简称集,使用存储多个元素的容器

2.集合和数组的区别

  • 元素性:
    集合:引用类型(存储基本类型时自动装箱)
    数组:基本类型、引用类型
  • 元素个数
    集合:不固定,可以任意扩容
    数组:固定,不能改变容量,列如定义一个int类型长度为5的数组只能最多存入5个在多就不行了
  • 集合的好处
    不受容器大小限制,可以随时添加、删除元素
    提供了大量操作元素的方法(判断、获取等)

3.集合简介

  • java的集合体系
    单例集合(Collection)
    List:ArrayList
    Set: HashSet
  • 双列集合(Map:key,value)
    Map:HashMap
    🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱

一、List集合特点应用

1.List集合的特点

  • 特点:可重复、有序(存取顺序相同)
  • 应用:List list = new ArrayList();父接口指向子类对象

2.需求

  • 往List集合中添加3个动物,然后遍历

2.1、创建动物实体类

package list;
public class Animal {
    private String name;
    private Integer age;

    public Animal() {}
    public Animal(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public String toString() {
        return "Animal{" + "name='" + name + '\'' + ", age=" + age + '}';
    }
   
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    
    public Integer getAge() {return age;}
    public void setAge(Integer age) {this.age = age;}
}

2.2、动物测试类

package list;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class Text {
    public static void main(String[] args) {
 //创建集合对象
        List list =new ArrayList();
        //创建元素对象
        Animal animal1 = new Animal("狗",4);
        Animal animal2 = new Animal("狗",4);
        Animal animal3 = new Animal("猫",6);
        Animal animal4 = new Animal("狮子",9);
        //将元素添加到对象中
        list.add(animal1);
        list.add(animal2);
        list.add(animal3);
        list.add(animal4);
        
        //List常用的一些方法
 		//获取索引为2的元素
        Object obj = list.get(2);
        System.out.println("索引为2的元素是:"+obj);
        //获取集合元素的个数
        System.out.println("集合的长度为:"+list.size());
  }
2.2.1、遍历集合
直接打印集合
System.out.println("----------直接打印集合--------------------");
        //直接打印集合
        System.out.println(list);
普通遍历集合
System.out.println("----------普通遍历集合--------------------");
        //普通遍历集合
        for (int i = 0; i < list.size(); i++) {
            Object obj2 = list.get(i);
            System.out.println("索引为"+i+"的元素是"+obj2);
        }
增强for循环遍历集合
 System.out.println("----------增强for循环遍历集合--------------------");
        //增强for循环遍历集合
        int i =0;
        for (Object obj3:list) {
            System.out.println("索引为"+(i++)+"的元素是"+obj3);
        }
2.2.2、通过迭代器遍历集合:

1. 为什么需要迭代器?

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

2. 迭代器的常用方法

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

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

通过普通迭代器遍历集合
  System.out.println("-----------通过普通迭代器遍历集合------------------");
  //通过普通迭代器遍历集合
   //使用步骤:
        // 1,根据集合对象获取其对象的选代器对象
        Iterator it= list.iterator();
        // 判断选代器中是否有元素
        while (it.hasNext()){//如果迭代器中有元素,就一直迭代
            //如果有就获取元素
            Object obj4 = it.next();
            System.out.println(obj4);
        }
通过列表迭代器遍历集合
 System.out.println("-----------通过列表迭代器遍历集合------------------");
        //列表迭代器使用
        //需求:判断集合中如果有字符串“葡萄”,就在其后边添加一个新的字符串“梨子”
        List list2 = new ArrayList();
        list2.add("苹果");
        list2.add("香蕉");
        list2.add("葡萄");
        //使用步骤:
        // 1,根据集合对象获取其对象的选代器对象
        ListIterator lit = list2.listIterator();
        // 判断选代器中是否有元素
        while (lit.hasNext()){//如果迭代器中有元素,就一直迭代
            //如果有就获取元素
            Object obj4 = lit.next();
            if("葡萄".equals(obj4)){
                //必须通过调用列表选代器的方法来实现
                lit.add("梨子");
            }
            System.out.println(obj4);
        }
        //打印新的list2的值
        System.out.println(list2);
    }

总结:
普通的选代器在遍历集合的同时不能添加或者删除元素,否则会报:并发修改异常
列表选代器在適历集合的同时可以修改集合中的元素(添加,删除等),必须使用列表选代器中的方法.

🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱

二、泛型简介

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

1.集合类泛型的解释

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

  • 案例演示(给List集合加上泛型String)
    List list = new ArrayList<>()
  • 泛型的好处
    类型安全
    避免了类型转换
import java.util.ArrayList;
import java.util.List;
public class Test {
    public static void main(String[] args) {
        //演示泛型
        //创建集合对象
        //泛型写成<String>只能写String类型数据,写其他类型的报错 ,”list.add(10);”报错
        List<String> list = new ArrayList<>();
        //创建元素对象
        //将元素对象添加到集合对象中
        list.add("飞机");
        list.add("火车");
        list.add("汽车");
        //遍历集合
        for(String s:list){
            System.out.println(s);
        };
    }
}

总结: 泛型一般只和集合类相结合使用。
泛型是JDK5的新特性,但是从JDK7开始,后边的泛型可以不用写具体的数据类型了(菱形泛型.)new ArrayList《string》() ,可以写成new ArrayList<>()

🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱

三、Collections工具类

1.Collections简介

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

2.常用的成员方法

※根据元素的自然顺序,将指定列表按升序排序
sort(List<T>) 	
※返回集合的最大元素
max(Collection<T>)
※反转List集合元素
reverse(List<T>)
※使用默认的随机源随机置换指定的列表
shuffle(List<T>)

🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱

四、 Set集合的特点和应用

  • Set集合的特点特点:不可重复、无序
  • 应用:Set set = new HashSet<>0;

4.案例: Set集合的简单使用

  • 4.1、需求:

向Set集合中添加五个元素,并遍历打印

  • 4.2、分析:

A. 向集合中添加元素的方法为: add()
B. 遍历集合的方式:选代器

  • 4.3、步骤:

1.创建集合对象:Set set = new HashSet<>();
2.分别创建五个Student对象
3.使用add方法将Student对象添加到集合中
4.使用选代器遍历集合并打印,注意添加顺序和打印顺序是否相同

4.4、创建学生实体类
import java.util.Objects;
public class Student {
    private String name;
    private Integer age;

    public Student() {}
    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" + "name='" + name + '\'' + ", age=" + age + '}';
    }
    
    public String getName() {return name;}

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

    public Integer getAge() {return age;}

    public void setAge(Integer age) {this.age = age;}
}
4.5、创建测试类
import java.util.HashSet;
import java.util.Set;
public class Text {
    public static void main(String[] args) {
        //创建集合对象
        Set<Student> set = new HashSet<>();
        //创建对象
        Student student1 = new Student("张三",12);
        Student student2 = new Student("李四",26);
        Student student3 = new Student("李四",48);
        Student student4 = new Student("王五",35);
        Student student5 = new Student("张三",12);
        Student student6 = new Student("李四",26);
        //将集合对象添加到元素对象中
        set.add(student1);
        set.add(student2);
        set.add(student3);
        set.add(student4);
        set.add(student5);
        set.add(student6);
    }
}
直接遍历循环
        //直接遍历集合
        System.out.println(set);
通过迭代器遍历集合
        Iterator it = set.iterator();
        //判断迭代器是否有元素
        while (it.hasNext()){
            //如果有元素,就获取元素
            System.out.println(it.next());
        }
通过增强for遍历Set集合
        for (Student student:set){
            System.out.println(student);
        }
4.6、set集合一些问题
  • 遍历集合为什么Set集合没有"去重"?
    1.因为Set集合保证元素的唯一性依赖: equals()和hashCode ()两个方法。
    2.你没有在Student类中重写这两个方法,默认调用的是0bject类中的这两个方法。
    3.而Object类中的equals()方法默认比较的是地址值是否相
  • 解决方案:
    在Student实体类中重写equsls()和hashCode()方法.
 @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return Objects.equals(name, student.name) && Objects.equals(age, student.age);
    }
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱

五、Map集合的特点和应用

5.1、Map集合的特点特点:

双列集合,元素由键值对(Entry)构成:key – value
key不可以重复,value可以重复

5.2、应用:

Map<T1, T2> map = new HashMap<>();
案例:Map集合的简单使用
需求:向Map集合中添加三个元素,并遍历打印

5.3、分析:

A. 向map集合中添加元素的方法为:put)
B. 遍历集合的方式:获取所有的key: keySet()遍历keySet,通过key获取value: get)
C. 遍历keySet的方法: iterator()

5.4、步骤:

1.创建集合对象:Map<Integer, Student> map = new HashMap<>();
2.分别创建三个Student对象
3.使用put方法将Student对象添加到集合中
4.获取所有的key,并使用选代器遍历
5.通过key分别获取对应的value并打印

5.5、创建学生实体类

import java.util.Objects;
public class Student {
    private String name;
    private Integer age;

    public Student() {}

    public Student(String name, Integer age) {
        this.name = name;
        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 Objects.equals(name, student.name) && Objects.equals(age, student.age);
    }

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

    public String getName() {return name;}

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

    public Integer getAge() {return age;}

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

5.6、创建测试类

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
    /*
        Map集合的特点特点:
            双列集合,元素由键值对(Entry)构成:
            key (键) - value (值)
        注意:
            健(key)不可以重复,值(value)可以重复
        应用:
            Map<TI, T2) map = new HashMap<>();
            解释:
                T1:表示键的数据类型
                T2:表示值的数据类形
     */

    /*
        成员方法:
            V put (K key, V value): 添加元素(健值对的形式),
                                    元素第一次添加,返回null,
                                    重复添加,会用新值覆盖旧值,并返回旧值.

            V get (Object key):     根据键获取其对应的值
            Set(K) keySet ():       获取所有键的集合

        遍历步骤:
            1.获取所有键的集合 keySet()
            2.遍历所有的键,获取到每一个键 迭代器,增强for.
            3.根据建,获取指定的值.  get();

    */
public class Test {
    public static void main(String[] args) {
        //创建集合对象
        //键:学生的编号, 值:具体的学生的对象
        Map<Integer,Student> map = new HashMap<>();
        //创建元素
        Student s1 =  new Student("张三",25);
        Student s2 =  new Student("李四",28);
        Student s3 =  new Student("张三",25);
        //将元素添加到集合中
        map.put(1,s1);
        map.put(2,s2);
        map.put(3,s3);      
    }
}

5.7、直接打印

 //根据建,获取值
        Student stu = map.get(3);
        System.out.println(stu);
        //直接打印集合
        System.out.println(map);

5.8、 增强for循环

  //增强for循环
        //获取到所有的键
        Set<Integer> keys1 = map.keySet();
       for (Integer key:keys1){
            //keys1就是双列集合中的每一个键
           System.out.println(map.get(key));
       }
5.9、迭代器遍历集合
 //遍历集合
        // 1.获取所有键的集合                keySet() 具有唯一性
        Set<Integer> keys = map.keySet();
        // 2.遍历所有的键,获取到每一个键      迭代器,增强for.
        //  获取迭代器对象
        Iterator<Integer> iterator = keys.iterator();
        while (iterator.hasNext()){
            Integer key = iterator.next();
            System.out.println(map.get(key));
        }

🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱

六、终极:用集合模拟斗地主

6.1、模拟斗地主发牌之买牌

6.1.1、案例:模拟斗地主发牌

  • 需求:使用一个集合对象存储一副扑克牌,将所有扑克牌的顺序打乱然后分发给用集合表示的三个玩家和底牌,并打印玩家和底牌的集合内容
  • 步骤:
    1.买一副扑克牌将花色和数字分别进行组合,生成所有的普通牌手动添加“大王”、“小王”
    2.洗牌使用Collections工具类的shuffle()方法打乱牌的顺序
    3.发牌遍历牌堆,将每一张牌分发到三个玩家集合中留三张作为底牌
    4.看牌分别打印每个玩家集合的内容

步骤一:买一副扑克牌

  • 分析:
    1.创建数字数组:String[] nums =(“3”,“4”,“5”,“6”,“7”,“8”,“9”,“10”,“J”,“Q”,“K”,“A”,“2”);
    2.创建花色数组:String[] colors = [“方片”,“梅花”,“红桃”,“黑桃”);
    3.将每一个花色分别和数字进行拼接colors[i].concat(nums[j]);
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Text {
    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;
                //奖牌的编号,具体的牌放到双列集合中
                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);

步骤二、三:洗牌和发牌

  • 分析:
    1.使用Collections工具类的shuffle()方法打乱牌堆集合的顺序
    2.分别创建三个玩家集合对象和底牌集合对象
    3.遍历牌堆的每一张牌,分别将索引对3取模的值为0,1,2的牌存放到三个玩家集合中,将最后三张存放到底牌集合中
//2.洗牌
        Collections.shuffle(list);
        System.out.println("洗好牌后,编号为:"+list);

        //3、发牌
        //3.1、定义四个集合,分别表示3个玩家,底牌.
        List<Integer> zhangsan = new ArrayList<>();
        List<Integer> lisi = new ArrayList<>();
        List<Integer> wangwu = new ArrayList<>();
        List<Integer> dipai = new ArrayList<>();

        //3.2、具体的发牌动作,将索引和3取模,决定发给谁
        for (int i = 0; i < list.size(); i++) {
            //获取编号
            Integer pokerNum = list.get(i);
            if(i >= list.size() - 3){
                //底牌
                dipai.add(pokerNum);
            }else if(i % 3 == 0){
                zhangsan.add(pokerNum);
            }else if(i % 3 == 1){
                lisi.add(pokerNum);
            }else if(i % 3 == 2){
                wangwu.add(pokerNum);
            }
        }
        //3.3、查看具体的牌
        System.out.println("张三:"+printPoker(zhangsan, pokers));
        System.out.println("李四:"+printPoker(lisi, pokers));
        System.out.println("王五:"+printPoker(wangwu, pokers));
        System.out.println("底牌:"+printPoker(dipai, pokers));
        }
   

步骤四、看牌

  • 分析:
    1.将玩家集合中的牌按自然顺序进行排序Collections.sort(List);
    2.打印玩家集合中的牌
    3.重复上面的操作打印所有玩家的牌和底牌
 /* 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();
    }
}

※最后输出

在这里插入图片描述

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SuperProgMan.SYJ

你的鼓励将是我创作更大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值