Live2D

集合

Java集合概述

如何学习本小节?

根据API文档使用步骤查找集合类;

查找集合类

查看该集合所属接口名

查看构造方法

 

背诵

创建集合对象

创建元素对象

添加元素到集合中

遍历集合

 

代码知识∶多练习,多操作

记住集合体系中各接口集合的特点

练习集合的基本操作(四个步骤)(重点)

 

集合简介

 

什么是集合?

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

集合和数组的区别

◆元素类型

集合∶引用类型(存储基本类型时自动装箱)

数组:基本类型、引用类型

◆元素个数

集合:不固定,可任意扩容

数组:固定,不能改变容量

◆集合的好处

不受容器大小限制,可以随时添加、删除元素提供了大量操作元素的方法(判断、获取等)

Java的集合体系

  1. 单例集合(Collection)

List: ArrayList

Set: HashSet

  1. 双例集合(Map:key,value)

Map: HashMap

Collections工具类

Collections简介

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

成员方法:

sort(List<T>):根据元素的自然顺序,将指定列表按升序排序

max(Collection<T>):返回集合的最大元素

reverse(List<T>):反转List集合元素

shuffle(List<T>):使用默认的随机源随机置换指定的列表

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

/*
Collections简介
       针对集合进行操作的工具类。
       成员方法
       sort(List<T>):根据元素的自然顺序,将指定列表按升序排序
       max(Collection<T>):返回集合的最大元素
       reverse(List<T>):反转List集合元素
       shuffle(List<T>):使用默认的随机源随机置换指定的列表

*/
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(4);
       //打印集合
       System.out.println("原先的集合:"+list);
       System.out.println("--------------");


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


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



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


       //需求对集合进行降序排序
       //1.先对集合进行升序
//       Collections.sort(list);
//       //2.再反转集合
//       Collections.reverse(list);
//       System.out.println("降序后的结果为:"+list);



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


  }
}

Set集合

HashSet 是 Set 接口的典型实现,大多数时候使用 Set 集合时都使用这个实现类。我们大多数时候说的set集合指的都是HashSet

HashSet 按 Hash 算法来存储集合中的元素,因此具有很好的存取和查找性能。

HashSet 具有以下特点:

不能保证元素的排列顺序

不可重复

HashSet 不是线程安全的

集合元素可以使 null

当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,然后根据 hashCode 值决定该对象在 HashSet 中的存储位置。

如果两个元素的 equals() 方法返回 true,但它们的 hashCode() 返回值不相等,hashSet 将会把它们存储在不同的位置,但依然可以添加成功。

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/*案例:
       Set集合的简单使用
       需求:向Set集合中添加五个元素,并遍历打印分析:
       A.向集合中添加元素的方法为:add()
       B.遍历集合的方式:迭代器
       步骤∶
       1.创建集合对象∶Set<Student> set = new HashSet<>();
       2.分别创建五个Student对象
       3.使用add方法将Student对象添加到集合中
       4.使用迭代器遍历集合并打印,注意添加顺序和打印顺序是否相同
       注意:
       Set集合保证元素的唯一性依赖 equals()和hashCode()两个方法
       */
public class Test {
   public static void main(String[] args) {
//需求:往set集合中添加五个学生对象,然后遍历
       //创建集合对象
       Set<Student> set = new HashSet<>();
       //创建元素对象
       Student s1 = new Student("乔峰",38);
       Student s2 = new Student("乔峰",38);
       Student s3 = new Student("虚竹",30);
       Student s4 = new Student("段誉",28);
       //将元素对象添加添加到集合对象里
       set.add(s1);
       set.add(s2);
       set.add(s3);
       set.add(s4);
       //遍历集合
       /*为什么Set集合没有"去重"?
       因为Set集合保证元素的唯一性依赖:equals()和 hashCode()两个方法.

       你没有在Student类中重写这两个方法,默认调用的是0bject类中的这两个方法.
       而Object类中的equals()方法默认比较的是地址值是否相同.

       解决方案:在Student类中重写equals()和hashCode()方法.
               */
       System.out.println(set);
       System.out.println("-------------");
       //通过迭代器遍历Set集合
       //1.通过集合对象获取迭代器对象
       Iterator<Student> it = set.iterator();
       //2.判断集合中是否有元素
       while (it.hasNext()){
           //3.如果有,获取元素
           Student s = it.next();
           System.out.println(s);
      }

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

Map集合

特点∶

双列集合,元素由键值对( Entry )构成:

key -- value

key不可以重复,value可以重复

应用:

Map<T1,T2> map = new HashMap<>();

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/*案例:Map集合的简单使用
       需求:向Map集合中添加三个元素,并遍历打印分析:

       A.向map集合中添加元素的方法为:put()
       元素第一次添加,返回null,重复添加,
       会用新值覆盖旧值,并返回旧值

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


       成员方法:
        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集合中添加三个学生对象,然后打印
       //创建集合对象
       //键:学生的编号 值:具体的学生对象
       Map<Integer,Student> map = new HashMap<>();
       //创建元素对象
       Student s1 = new Student("张三",20);
       Student s2 = new Student("李四",22);
       Student s3 = new Student("小马",21);


       //将元素对象添加到集合对象里 map.put();
      /* Student p1 = map.put(1, s1);
       System.out.println(p1);
       Student p2 = map.put(1, s2);
       System.out.println(p2);*/
       map.put(1,s1);
       map.put(2,s2);
       map.put(3,s3);


       //根据键,获取值 map.get(键);
       Student stu = map.get(2);
       System.out.println(stu);
       //打印集合
       System.out.println(map);
       //遍历集合
      /* //1.获取所有键的集合.             keySet()双例集合变单例集合
       Set<Integer> keys = map.keySet();
       //2.遍历所有的键,获取到每一个键.   迭代器,增强for.
       //获取迭代器对象
       Iterator<Integer> it = keys.iterator();
       //判断迭代器是否有数据
       while (it.hasNext()){
           Integer key = it.next();//如果有,就获取
           ////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 stu1 = map.get(key);
           System.out.println("key:"+key+"...value:"+stu1);

      }

  }
}

List集合

特点:可重复、有序(存取顺序相同)

应用: List list = new ArrayList();


//学生类
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;

/*
单列集合(Collection)之List集合:
特点:
有序(元素的存取顺序一致),可重复.
注意:
List是接口,所以可以通过创建其子类ArrayList对象来完成该接口的实例化.
List list = new ArrayList ();
List接口中的成员方法:
public boolean add(E e);//将数据添加到集合的末尾,这里的E是泛型的意思,目前可以先理解为Object类型.
public E get(int index);//根据索引,索取其对应的元素.
public int size() ;//获取集合的长度.
使用集合的步骤:
 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("乔峰",38);
       Student s2 = new Student("乔峰",38);
       Student s3 = new Student("虚竹",30);
       Student s4 = new Student("段誉",28);
//       3.添加元素到集合中
       list.add(s1);
       list.add(s2);
       list.add(s3);
       list.add(s4);
       //直接打印集合
       System.out.println(list);
       //public E get(int index);//根据索引,索取其对应的元素.
       Object obj1=list.get(2);
       System.out.println("索引为2的元素:"+obj1);
       //获取集合中的个数
       //public int size() ;//获取集合的长度.
       System.out.println("集合的长度为:"+list.size());
       System.out.println("---------------------");
//       4.遍历集合

       for (int i = 0; i < list.size(); i++) {
           //i表示集合中元素的索引
           //获取元素
           Object obj2=list.get(i);
           System.out.println("索引为"+i+"元素是"+obj2);
      }

  }
}

增强for循环和迭代器

1.为什么需要增强for循环?

简化数组和集合的遍历

2.增强for循环的格式:

for(数据类型变量名︰数组或者集合对象){

循环体,变量即元素

}

注意:增强for的底层依赖的就是迭代器(Iterator)

大白话解释:增强for就是迭代器的简写形式

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

/*
增强for循环的格式:
for(数据类型变量名︰数组或者集合对象){
循环体,变量即元素
}
注意:增强for的底层依赖的就是迭代器(Iterator)
大白话解释:增强for就是迭代器的简写形式
*/
public class Test {
   public static void main(String[] args) {
       //需求:通过增强For遍历list
       //创建集合对象
       List list = new ArrayList();
       //创建元素对象
       //将元素对象添加到集合对象里
             list.add(10);
             list.add(10);
             list.add(20);
             list.add(30);
       //遍历集合
       for (Object obj:list) {
           //obj是集合中的元素,其本身应该是Integer
           Integer ii = (Integer) obj;
           System.out.println(ii);
      }
       System.out.println("----------------");
       //快捷键 iter
       for (Object obj1 : list) {
           Integer ii = (Integer) obj1;
           System.out.println();

      }
  }

}

 

为什么需要迭代器?

对过程的重复,称为迭代。

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

迭代器的常用方法:

next():返回迭代的下一个元素对象

hasNext()∶如果仍有元素可以迭代,则返回true

迭代器的使用步骤:
1.根据集合对象获取相应的迭代器对象。
2.判断迭代器是否有元素
3.如果有就获取元素
总结:普通迭代器在遍历的同时不能做添加删除元素,否则会报并发修改异常
列表迭代器在遍历的同时能做添加删除元素,但必须调用列表迭代器对象的方法。
public class Test1 {
   public static void main(String[] args) {
    //创建集合对象
       List list = new ArrayList();
       //创建元素对象
       //将元素对象添加到集合对象中
       list.add("a");
       list.add("b");
       list.add("c");
       //遍历集合
      // 迭代器的使用步骤:
      /* //1.根据集合对象获取相应的迭代器对象。
      Iterator it = list.iterator();
       //2.判断迭代器是否有元素
       while (it.hasNext()){//如果有元素,就一直迭代
           //3.如果有就获取元素
           String s = (String)it.next();
           System.out.println(s);
       }*/
       System.out.println("-------------------------");
       //需求;判断集合中是否有"b",在其后面添加一个字符串"java"
       //1.根据集合对象获取相应的迭代器对象。
       Iterator it =  list.iterator();
       //2.判断迭代器是否有元素
       while (it.hasNext()){//如果有元素,就一直迭代
           //3.如果有就获取元素
           String s = (String)it.next();
           if ("b".equals(s)){//这样写规避空指针异常
              //走到这,说明集合中有"b"
               list.add("java");//这样写不行,会报ConcurrentModificationException异常
               //要用列表迭代器
          }
           System.out.println(s);
      }
  }
}
列表迭代器
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

/*注意:列表迭代器是List独有的遍历方式,可以对集合遍历的同时进行添加删除等操作。
       但是必须通过列表迭代器的方法实现*/
public class Test2 {
   public static void main(String[] args) {
       //测试列表迭代器
       //创建集合对象
       List list = new ArrayList();
       //创建元素对象
       //将元素对象添加到集合对象中
       list.add("a");
       list.add("b");
       list.add("c");
       //需求;判断集合中是否有"b",在其后面添加一个字符串"java"
      // 1.根据集合对象获取相应的迭代器对象。
       ListIterator listIterator = list.listIterator();
       //2.判断迭代器是否有元素
       while (listIterator.hasNext()){
           String s = (String)listIterator.next();
           //3.如果有就获取元素
           if ("b".equals(s)){
               listIterator.add("java");//必须调用迭代器的方法实现
          }
           System.out.println(s);
      }
       System.out.println("------------------");
    //打印集合中的元素
       System.out.println(list);
  }
}

泛型

什么是泛型?

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

集合类泛型的解释

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

案例演示(给List集合加上泛型String )

List<String> list = new ArrayList<>();

泛型的好处

  1. 类型安全

  2. 避免了类型转换

import java.util.ArrayList;
import java.util.List;
//总结:泛型一般只和集合类相结合使用。
//泛型是JDK5新特性,但是从JDK7开始,后面的泛型不用写具体的数据类型了,简称菱形泛型
public class Test1 {
   public static void main(String[] args) {
      /* //不使用泛型的集合
       //创建集合对象
       List list = new ArrayList();
       //创建元素对象
       //将元素对象添加到集合对象中
       list.add("a");
       list.add("b");
       list.add("c");
       //list.add(10);不能这样写,会报类型转换异常ClassCastException
       //遍历集合
       for (Object obj : list) {
           String s = (String)obj;
           System.out.println(s);
       }
       System.out.println("-----------------");*/
       //演示泛型
       //创建集合对象
   List<String> list = new ArrayList<>();
       //创建元素对象
       //将元素对象添加到集合对象中
         list.add("abc");
          list.add("bcd");
          list.add("def");
       //遍历集合
       for (String s : list) {
           System.out.println(s);
      }
  }


}

模拟斗地主发牌功能

案例:模拟斗地主发牌

需求:使用一个集合对象存储一副扑克牌,将所有扑克牌的顺序打乱,然后分发给用集合表示的三个玩家和底牌,

并打印玩家和底牌的集合内容 步骤;

1.买一副扑克牌

将花色和数字分别进行组合,生成所有的普通牌手动添加“大王”、“小王”

2.洗牌

使用Collections工具类的shuffle()方法打乱牌的顺序

3.发牌

遍历牌堆,将每一张牌分发到三个玩家集合中留三张作为底牌

4.看牌

分别打印每个玩家集合的内容

import java.util.*;

public class SendPokerTest {
   public static void main(String[] args) {
       //步骤一∶买一副扑克牌
       //1.1定义一个双例集合,键:表示牌的编号,值:表示具体的值。规则:编号越小,牌越小
       Map<Integer,String> pokers = new HashMap<>();
       //1.2定义一个单例集合,用来储存所有牌的编号
       List<Integer> list = new ArrayList<>();
       //1.3具体的买牌动作
       //普通牌 52
       int num = 0 ;//表示牌的编号
       String[] colors = {"♠","♥","♣","♦"};
       String[] numbers = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
       //通过循环嵌套,获得牌
       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);

       //1.4打印牌就可以了
       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定义4个集合,分别表示三个玩家,底牌
       List<Integer> xiaofei = new ArrayList<>();
       List<Integer> xiaohao = new ArrayList<>();
       List<Integer> xiaoma = 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){
               xiaofei.add(pokerNum);
          }else if (i%3==1){
               xiaohao.add(pokerNum);
          }else if (i%2==0){
               xiaoma.add(pokerNum);
          }
      }
       /*//3.3查看玩家底牌编号
       System.out.println("xiaofei:"+xiaofei);
       System.out.println("xiaohao:"+xiaohao);
       System.out.println("xiaoma:"+xiaoma);
      System.out.println("dipai:"+dipai);*/
       //4.查看具体的牌
//       String str1 = printPoker(xiaofei, pokers);
//       System.out.println("xiaofei"+str1);
       System.out.println("xiaofei:"+printPoker(xiaofei,pokers));
       System.out.println("xiaohao:"+printPoker(xiaohao,pokers));
       System.out.println("xiaoma:"+printPoker(xiaoma,pokers));
       System.out.println("dipai:"+printPoker(dipai,pokers));
        /*步骤四:看牌
       分析:
       1.将玩家集合中的牌按自然顺序进行排序
       Collections.sort(List);
       2.打印玩家集合中的牌
       3.重复上面的操作打印所有玩家的牌和底牌*/
       //定义一个方法,用来看牌
       //方法名: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();
  }
}
posted @ 2021-01-28 19:25  MWTYING  阅读(98)  评论(0)    收藏  举报