我是靠谱客的博主 殷勤白昼,最近开发中收集的这篇文章主要介绍集合--java常用APICollection集合List系列集合的使用Set系列集合Collections工具类的使用引用数据类型的排序斗地主游戏的案例开发Map集合,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

在这里插入图片描述

Collection集合

Collection集合的概述

package com.itheima._14Collection集合的概述;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;

/**
    什么是集合?
        集合是一个大小可变的容器。
        容器中的每个数据称为一个元素。数据==元素。
        集合的特点是:类型可以不确定,大小不固定。集合有很多种,不同的集合特点和使用场景不同。
        数组:类型和长度一旦定义出来就都固定了。

    集合有啥用?
        在开发中,很多时候元素的个数是不确定的。
        而且经常要进行元素的增删该查操作,集合都是非常合适的。
        开发中集合用的更多!!

    Java中集合的代表是:Collection.
    Collection集合是Java中集合的祖宗类。
    学习Collection集合的功能,那么一切集合都可以用这些功能!!

    Collection集合的体系:
                            Collection<E>(接口)
                      /                                
                 Set<E>(接口)                            List<E>(接口)
                /                                      /                
             HashSet<E>(实现类)  TreeSet<>(实现类)     ArrayList<E>(实现类)  LinekdList<>(实现类)
             /
         LinkedHashSet<>(实现类)

    集合的特点:
          Set系列集合:添加的元素是无序,不重复,无索引的。
                -- HashSet:添加的元素是无序,不重复,无索引的。
                -- LinkedHashSet:添加的元素是有序,不重复,无索引的。
                -- TreeSet:不重复,无索引,按照大小默认升序排序!!
          List系列集合:添加的元素是有序,可重复,有索引。
                -- ArrayList:添加的元素是有序,可重复,有索引。
                -- LinekdList:添加的元素是有序,可重复,有索引。
    小结:
        Collection是集合的祖宗类,Collection集合的功能是一切集合都可以直接使用的。
 */
public class CollectionDemo01 {
    public static void main(String[] args) {
        // 多态写法:
        //  HashSet:添加的元素是无序,不重复,无索引的。
        Collection<String> sets = new HashSet<>();
        sets.add("MyBatis");
        sets.add("Java");
        sets.add("Java");
        sets.add("Spring");
        sets.add("MySQL");
        sets.add("MySQL");
        // [Java, MySQL, MyBatis, Spring]
        System.out.println(sets);

        // ArrayList:添加的元素是有序,可重复,有索引。
        Collection<String> lists = new ArrayList<>();
        lists.add("MyBatis");
        lists.add("Java");
        lists.add("Java");
        lists.add("Spring");
        lists.add("MySQL");
        lists.add("MySQL");
        // [MyBatis, Java, Java, Spring, MySQL, MySQL]
        System.out.println(lists);

    }
}

Collection集合的常用API

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;

/**
    目标:Collection集合的常用API.
    
    Collection是集合的祖宗类,它的功能是全部集合都可以继承使用的,所以要学习它。
    Collection API如下:
         - public boolean add(E e):  把给定的对象添加到当前集合中 。
         - public void clear() :清空集合中所有的元素。
         - public boolean remove(E e): 把给定的对象在当前集合中删除。
         - public boolean contains(Object obj): 判断当前集合中是否包含给定的对象。
         - public boolean isEmpty(): 判断当前集合是否为空。
         - public int size(): 返回集合中元素的个数。
         - public Object[] toArray(): 把集合中的元素,存储到数组中
    小结:
        记住以上API。
 */
public class CollectionDemo {
    public static void main(String[] args) {
        // HashSet:添加的元素是无序,不重复,无索引。
        Collection<String> sets = new HashSet<>();
        // 1.添加元素,添加成功返回true.
        System.out.println(sets.add("贾乃亮")); // true
        System.out.println(sets.add("贾乃亮")); // false
        System.out.println(sets.add("王宝强")); // true
        sets.add("陈羽凡");
        System.out.println(sets); // 集合重写了toString()方法,默认打印出内容信息
        // 2.清空集合的元素。
        //sets.clear();
        //System.out.println(sets);

        // 3.判断集合是否为空 是空返回true 反之
        System.out.println(sets.isEmpty()); // false

        // 4.获取集合的大小
        System.out.println(sets.size()); // 3

        // 5.判断集合中是否包含某个元素 。
        System.out.println(sets.contains("贾乃亮"));

        // 6.删除某个元素:如果有多个重复元素默认删除前面的第一个!
        sets.remove("陈羽凡");
        System.out.println(sets);

        // 7.把集合转换成数组
        Object[] arrs = sets.toArray();
        System.out.println("数组:"+ Arrays.toString(arrs));

        String[] arrs1 = sets.toArray(String[]::new); // 以后再了解,指定转换的数组类型!
        System.out.println("数组:"+ Arrays.toString(arrs1));

        System.out.println("---------------------拓展---------------------------");
        Collection<String> c1 = new ArrayList<>();
        c1.add("李小璐");
        c1.add("马蓉");

        Collection<String> c2 = new ArrayList<>();
        c2.add("白百合");

        c1.addAll(c2); // 把c2集合的元素全部倒入到c1
        System.out.println(c1);
    }
}

Collection集合的遍历方式

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
    目标:Collection集合的遍历方式。

    什么是遍历? 为什么开发中要遍历?
        遍历就是一个一个的把容器中的元素访问一遍。
        开发中经常要统计元素的总和,找最值,找出某个数据然后干掉等等业务都需要遍历。

    Collection集合的遍历方式是全部集合都可以直接使用的,所以我们学习它。
    Collection集合的遍历方式有三种:
        (1)迭代器。
        (2)foreach(增强for循环)。
        (3)JDK 1.8开始之后的新技术Lambda表达式(了解)

    a.迭代器遍历集合。
        -- 方法:
            public Iterator iterator(): 获取集合对应的迭代器,用来遍历集合中的元素的
            E next():获取下一个元素值!
            boolean hasNext():判断是否有下一个元素,有返回true ,反之。
        --流程:
            1.先获取当前集合的迭代器
                Iterator<String> it = lists.iterator();
            2.定义一个while循环,问一次取一次。
              通过it.hasNext()询问是否有下一个元素,有就通过
              it.next()取出下一个元素。
        小结:
            记住!
 */
public class CollectionDemo01 {
    public static void main(String[] args) {
        Collection<String> lists = new ArrayList<>();
        lists.add("赵敏");
        lists.add("小昭");
        lists.add("殷素素");
        lists.add("周芷若");
        System.out.println(lists);
        // lists = [赵敏, 小昭, 殷素素, 周芷若]
        //   it

        // 1.得到集合的迭代器对象。
        Iterator<String> it = lists.iterator();
//        System.out.println(it.next());
//        System.out.println(it.next());
//        System.out.println(it.next());
//        System.out.println(it.next());
//        System.out.println(it.next()); // 出现异常NoSuchElementException,出现没有此元素异常!

        // 2.使用while循环遍历。
        while(it.hasNext()){
            String ele = it.next();
            System.out.println(ele);
        }
    }
}
import java.util.ArrayList;
import java.util.Collection;
/**
     目标:Collection集合的遍历方式。

     什么是遍历? 为什么开发中要遍历?
     遍历就是一个一个的把容器中的元素访问一遍。
     开发中经常要统计元素的总和,找最值,找出某个数据然后干掉等等业务都需要遍历。

     Collection集合的遍历方式是全部集合都可以直接使用的,所以我们学习它。
     Collection集合的遍历方式有三种:
         (1)迭代器。
         (2)foreach(增强for循环)。
         (3)JDK 1.8开始之后的新技术Lambda表达式。

     b.foreach(增强for循环)遍历集合。
         foreach是一种遍历形式,可以遍历集合或者数组。
         foreach遍历集合实际上是迭代器遍历的简化写法。
         foreach遍历的关键是记住格式:
            for(被遍历集合或者数组中元素的类型 变量名称 : 被遍历集合或者数组){

            }
        小结:
            foreach遍历集合或者数组很方便。
            缺点:foreach遍历无法知道遍历到了哪个元素了,因为没有索引。

 */
public class CollectionDemo02 {
    public static void main(String[] args) {
        Collection<String> lists = new ArrayList<>();
        lists.add("赵敏");
        lists.add("小昭");
        lists.add("殷素素");
        lists.add("周芷若");
        System.out.println(lists);
        // lists = [赵敏, 小昭, 殷素素, 周芷若]
        //  ele
        for (String ele : lists) {
            System.out.println(ele);
        }


        int[] ages = new int[]{17 , 18 , 38 , 21};
        for (int age : ages) {
            System.out.println(age);
        }
    }
}
package com.itheima._01Collection集合的遍历方式;

import java.util.ArrayList;
import java.util.Collection;

/**
     目标:Collection集合的遍历方式。

     什么是遍历? 为什么开发中要遍历?
     遍历就是一个一个的把容器中的元素访问一遍。
     开发中经常要统计元素的总和,找最值,找出某个数据然后干掉等等业务都需要遍历。

     Collection集合的遍历方式是全部集合都可以直接使用的,所以我们学习它。
     Collection集合的遍历方式有三种:
         (1)迭代器。
         (2)foreach(增强for循环)。
         (3)JDK 1.8开始之后的新技术Lambda表达式。
     c.JDK 1.8开始之后的新技术Lambda表达式。(暂时了解)
 */
public class CollectionDemo03 {
    public static void main(String[] args) {
        Collection<String> lists = new ArrayList<>();
        lists.add("赵敏");
        lists.add("小昭");
        lists.add("殷素素");
        lists.add("周芷若");
        System.out.println(lists);
        //   [赵敏, 小昭, 殷素素, 周芷若]
        //   s
        lists.forEach(s -> {
            System.out.println(s);
        });
//      lists.forEach(s ->  System.out.println(s));
//      lists.forEach(System.out::println);
    }
}

List系列集合的使用

ArrayList集合

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Vector;

/**
      目标:ArrayList集合。

      Collection集合的体系:
                        Collection<E>(接口)
              /                                                
           Set<E>(接口)                                         List<E>(接口)
            /                                                 /                                       
          HashSet<E>(实现类)    TreeSet<E>(实现类)          LinkedList<E>(实现类) Vector(线程安全)     ArrayList<E>(实现类)
          /
         LinkedHashSet<E>(实现类)

      Collection集合体系的特点:
         Set系列集合: 添加的元素,是无序,不重复,无索引的。
             -- HashSet:添加的元素,是无序,不重复,无索引的。
             -- LinkedHashSet:添加的元素,是有序,不重复,无索引的。
         List系列集合:添加的元素,是有序,可重复,有索引的。
             -- LinkedList: 添加的元素,是有序,可重复,有索引的。
             -- ArrayList: 添加的元素,是有序,可重复,有索引的。
             -- Vector 是线程安全的,速度慢,工作中很少使用。

         List集合继承了Collection集合的全部功能,同时因为List系列集合有索引,
         因为List集合多了索引,所以多了很多按照索引操作元素的功能:
         ArrayList实现类集合底层基于数组存储数据的,查询快,增删慢!
             - public void add(int index, E element): 将指定的元素,添加到该集合中的指定位置上。
             - public E get(int index):返回集合中指定位置的元素。
             - public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。
             - public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回更新前的元素值。
        小结:
            List系列集合有序,可重复,有索引的。
            ArrayList实现类集合底层基于数组存储数据的,查询快,增删慢!!
            开发中ArrayList集合用的最多!!
 */
public class ListDemo01 {
    public static void main(String[] args) {
        // 1.创建一个ArrayList集合对象:这是一行经典代码!
        // List:有序,可重复,有索引的。
        List<String> lists = new ArrayList<>();
        lists.add("java1");
        lists.add("java1");
        lists.add("java2");
        lists.add("java2");
        System.out.println(lists);

        // 2.在某个索引位置插入元素。
        lists.add(2,"MySQL");
        System.out.println(lists);

        // 3.根据索引删除元素,返回被删除元素
        System.out.println(lists.remove(2));
        System.out.println(lists);

        // 4.根据索引获取元素
        System.out.println(lists.get(2)); // java2

        // 5.修改索引位置处的元素
        lists.set(3,"Mybatis");
        System.out.println(lists);
    }
}

List系列集合的使用

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

/**
    拓展:List系列集合的遍历方式有:4种。

    List系列集合多了索引,所以多了一种按照索引遍历集合的for循环。

    List遍历方式:
        (1)for循环。
        (2)迭代器。
        (3)foreach。
        (4)JDK 1.8新技术。
 */
public class ListDemo02 {
    public static void main(String[] args) {
        List<String> lists = new ArrayList<>();
        lists.add("java1");
        lists.add("java2");
        lists.add("java3");

        /** (1)for循环。 */
        for(int i = 0 ; i < lists.size() ; i++ ) {
            String ele = lists.get(i);
            System.out.println(ele);
        }
        System.out.println("-----------------------");

        /** (2)迭代器。 */
        Iterator<String> it = lists.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
        System.out.println("-----------------------");

        /** (3)foreach。 */
        for(String ele : lists){
            System.out.println(ele);
        }
        System.out.println("-----------------------");

        /** (4)JDK 1.8开始之后的Lambda表达式*/
        lists.forEach(s -> {
            System.out.println(s);
        });
    }
}

LinkedList集合

import java.util.LinkedList;
import java.util.List;

/**
     目标:LinkedList集合。

     Collection集合的体系:
                Collection<E>(接口)
     /                                       
     Set<E>(接口)                             List<E>(接口)
     /                                   /                                   
     HashSet<E>(实现类)                   LinkedList<E>(实现类) Vector(实现类)  ArrayList<E>(实现类)
     /
     LinkedHashSet<E>(实现类)

     Collection集合体系的特点:
         Set系列集合: 添加的元素,是无序,不重复,无索引的。
             -- HashSet:添加的元素,是无序,不重复,无索引的。
             -- LinkedHashSet:添加的元素,是有序,不重复,无索引的。
         List系列集合:添加的元素,是有序,可重复,有索引的。
             -- LinkedList: 添加的元素,是有序,可重复,有索引的。
             -- ArrayList: 添加的元素,是有序,可重复,有索引的。

     LinkedList也是List的实现类:底层是基于链表的,增删比较快,查询慢!!
     LinkedList是支持双链表,定位前后的元素是非常快的,增删首尾的元素也是最快的
     所以LinkedList除了拥有List集合的全部功能还多了很多操作首尾元素的特殊功能:
         - public void addFirst(E e):将指定元素插入此列表的开头。
         - public void addLast(E e):将指定元素添加到此列表的结尾。
         - public E getFirst():返回此列表的第一个元素。
         - public E getLast():返回此列表的最后一个元素。
         - public E removeFirst():移除并返回此列表的第一个元素。
         - public E removeLast():移除并返回此列表的最后一个元素。
         - public E pop():从此列表所表示的堆栈处弹出一个元素。
         - public void push(E e):将元素推入此列表所表示的堆栈。

    小结:
         LinkedList是支持双链表,定位前后的元素是非常快的,增删首尾的元素也是最快的。
         所以提供了很多操作首尾元素的特殊API可以做栈和队列的实现。

         如果查询多而增删少用ArrayList集合。(用的最多的)
         如果查询少而增删首尾较多用LinkedList集合。
 */
public class ListDemo03 {
    public static void main(String[] args) {
        // 1.用LinkedList做一个队列:先进先出,后进后出。
        LinkedList<String> queue = new LinkedList<>();
        // 入队
        queue.addLast("1号");
        queue.addLast("2号");
        queue.addLast("3号");
        queue.addLast("4号");
        System.out.println(queue); // [1号, 2号, 3号, 4号]
        // 出队
        System.out.println(queue.removeFirst());
        System.out.println(queue.removeFirst());
        System.out.println(queue);

        // 做一个栈
        LinkedList<String> stack = new LinkedList<>();
        // 压栈
        stack.push("第1颗子弹");
        stack.push("第2颗子弹");
        stack.push("第3颗子弹");
        stack.push("第4颗子弹");
        System.out.println(stack); // [第4颗子弹, 第3颗子弹, 第2颗子弹, 第1颗子弹]
        // 弹栈
        System.out.println(stack.pop());
        System.out.println(stack.pop());
        System.out.println(stack);
    }
}

Set系列集合

HashSet集合

package com.itheima._04Set系列集合;
import java.util.*;

/**
  目标:HashSet集合

  Collection集合的体系:
                      Collection<E>(接口)
                /                                       
             Set<E>(接口)                             List<E>(接口)
              /                                          /                                    
         HashSet<E>(实现类) TreeSet<E>(实现类)       LinkedList<E>(实现类) Vector(线程安全)     ArrayList<E>(实现类)
            /
        LinkedHashSet<E>(实现类)

  Collection集合体系的特点:
         Set系列集合: 添加的元素,是无序,不重复,无索引的。
             -- HashSet:添加的元素,是无序,不重复,无索引的。
             // -- LinkedHashSet:添加的元素,是有序,不重复,无索引的。
             -- TreeSet: 不重复,无索引,按照大小默认升序排序!! ( 可排序集合 )
         List系列集合:添加的元素,是有序,可重复,有索引的。
             -- LinkedList: 添加的元素,是有序,可重复,有索引的。底层是基于链表存储数据的,查询慢,增删快
             -- ArrayList: 添加的元素,是有序,可重复,有索引的。底层基于数组存储数据的,查询快,增删慢

    研究两个问题(面试热点):
        1)Set集合添加的元素是不重复的,是如何去重复的?
        2)Set集合元素无序的原因是什么?

 */
public class HashSetDemo01 {
    public static void main(String[] args) {
        // 无序,不重复,无索引的。
        Set<String> sets = new HashSet<>(); // 一行经典代码!!
        sets.add("Mybatis");
        sets.add("Java");
        sets.add("Java");
        sets.add("MySQL");
        sets.add("MySQL");
        sets.add("Spring");
        // [Java, MySQL, Spring, Mybatis]
        System.out.println(sets);
    }
}

Set系列集合元素去重复的流程

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

/**
    目标:Set系列集合元素去重复的流程。

    集合和泛型都只能支持引用数据类型。

    1.对于有值特性的,Set集合可以直接判断进行去重复。
    2.对于引用数据类型的类对象,Set集合是按照如下流程进行是否重复的判断。
        Set集合会让两两对象,先调用自己的hashCode()方法得到彼此的哈希值(所谓的内存地址)
        然后比较两个对象的哈希值是否相同,如果不相同则直接认为两个对象不重复。
        如果哈希值相同,会继续让两个对象进行equals比较内容是否相同,如果相同认为真的重复了
        如果不相同认为不重复。

                Set集合会先让对象调用hashCode()方法获取两个对象的哈希值比较
                   /                     
                false                    true
                /                          
            不重复                        继续让两个对象进行equals比较
                                           /          
                                         false        true
                                          /             
                                        不重复          重复了

        需求:只要对象内容一样,就希望集合认为它们重复了。重写hashCode和equals方法。

    小结:
        如果希望Set集合认为两个对象只要内容一样就重复了,必须重写对象的hashCode和equals方法。
 */
public class HashSetDemo02 {
    public static void main(String[] args) {
        Set<Integer> sets = new HashSet<>(); // 一行经典代码!!
        sets.add(1);
        sets.add(1);
        sets.add(2);
        sets.add(2);
        System.out.println(sets);

        // 存储一些自定义类型数据:无序不重复
        Set<Apple> apples = new HashSet<>();
        Apple a1 = new Apple("红富士",59.9 ,"红色");
        Apple a2 = new Apple("阿克苏",39.9 ,"青红色");
        Apple a3 = new Apple("阿克苏",39.9 ,"青红色");
        System.out.println(a1.hashCode()); // 哈希值,相当于是内存地址
        System.out.println(a2.hashCode()); // 哈希值,相当于是内存地址
        System.out.println(a3.hashCode()); // 哈希值,相当于是内存地址
        apples.add(a1);
        apples.add(a2);
        apples.add(a3);
        System.out.println(apples);
    }
}

Set系列集合元素无序的根本原因。(面试必考)

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

/**
    目标:Set系列集合元素无序的根本原因。(面试必考)

    Set系列集合添加元素无序的根本原因是因为底层采用了哈希表存储元素。

    JDK 1.8之前:哈希表 = 数组 + 链表  + (哈希算法)
    JDK 1.8之后:哈希表 = 数组 + 链表 + 红黑树  + (哈希算法)
        当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。

    小结:
        Set系列集合是基于哈希表存储数据的
        它的增删改查的性能都很好!!但是它是无序不重复的!如果不在意当然可以使用!
 */
public class HashSetDemo03 {
    public static void main(String[] args) {
        Set<String> sets = new HashSet<>(); // 一行经典代码!!
        sets.add("Java");
        sets.add("Java");
        sets.add("Mybatis");
        sets.add("MySQL");
        sets.add("MySQL");
        sets.add("Spring");
        // [Java, MySQL, Spring, Mybatis]
        System.out.println(sets);
    }
}

LinkedHashSet

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

/**
    目标:LinkedHashSet

    是HashSet的子类,元素是“有序” 不重复,无索引.

    LinkedHashSet底层依然是使用哈希表存储元素的,
    但是每个元素都额外带一个链来维护添加顺序!!
    不光增删查快,还有序。缺点是多了一个存储顺序的链会占内存空间!!而且不允许重复,无索引。

    总结:
         如果希望元素可以重复,又有索引,查询要快用ArrayList集合。(用的最多)
         如果希望元素可以重复,又有索引,增删要快要用LinkedList集合。(适合查询元素比较少的情况,经常要首尾操作元素的情况)
         如果希望增删改查都很快,但是元素不重复以及无序无索引,那么用HashSet集合。
         如果希望增删改查都很快且有序,但是元素不重复以及无索引,那么用LinkedHashSet集合。
*/
public class HashSetDemo04 {
    public static void main(String[] args) {
        // 有序不重复无索引
        Set<String> sets = new LinkedHashSet<>();
        sets.add("Mybatis");
        sets.add("Java");
        sets.add("Java");
        sets.add("MySQL");
        sets.add("MySQL");
        sets.add("Spring");
        // [Java, MySQL, Spring, Mybatis]
        System.out.println(sets);
    }
}

TreeSet集合

import java.util.*;

/**
    目标:TreeSet集合。

    TreeSet: 不重复,无索引,按照大小默认升序排序!!
    TreeSet集合称为排序不重复集合,可以对元素进行默认的升序排序。

    TreeSet集合自自排序的方式:
        1.有值特性的元素直接可以升序排序。(浮点型,整型)
        2.字符串类型的元素会按照首字符的编号排序。
        3.对于自定义的引用数据类型,TreeSet默认无法排序,执行的时候直接报错,因为人家不知道排序规则。

    自定义的引用数据类型的排序实现:
        对于自定义的引用数据类型,TreeSet默认无法排序
        所以我们需要定制排序的大小规则,程序员定义大小规则的方案有2种:
        a.直接为对象的类实现比较器规则接口Comparable,重写比较方法(拓展方式)
             // 如果程序员认为比较者大于被比较者 返回正数!
             // 如果程序员认为比较者小于被比较者 返回负数!
             // 如果程序员认为比较者等于被比较者 返回0!

        b.直接为集合设置比较器Comparator对象,重写比较方法
             // 如果程序员认为比较者大于被比较者 返回正数!
             // 如果程序员认为比较者小于被比较者 返回负数!
             // 如果程序员认为比较者等于被比较者 返回0!
        注意:如果类和集合都带有比较规则,优先使用集合自带的比较规则。

    小结:
        TreeSet集合对自定义引用数据类型排序,默认无法进行。
        但是有两种方式可以让程序员定义大小规则:
             a.直接为对象的类实现比较器规则接口Comparable,重写比较方法(拓展方式)
             b.直接为集合设置比较器Comparator对象,重写比较方法
        注意:如果类和集合都带有比较规则,优先使用集合自带的比较规则。
 */
public class TreeSetDemo05 {
    public static void main(String[] args) {
        // TreeSet : 排序不重复集合。
        Set<Double> scores = new TreeSet<>();
        scores.add(100.0);
        scores.add(99.9);
        scores.add(69.5);
        scores.add(0.1);
        scores.add(89.3);
        System.out.println(scores);

        // 字符串按照首字符的编号进行排序。
        Set<String> names = new TreeSet<>();
        names.add("Jack");
        names.add("rose");
        names.add("Dlei");
        names.add("about");
        names.add("曹雪芹");
        names.add("bozai");
        names.add("caocao");
        names.add("angel");
        System.out.println(names);

        // 引用数据类型定义TreeSet集合。
        Set<Employee> employees = new TreeSet<>();
        employees.add(new Employee("播仔",6500.0,21));
        employees.add(new Employee("播妞",7500.0,19));
        employees.add(new Employee("乔治",4500.0,23));
        System.out.println(employees);


        // public TreeSet(Comparator<? super E> comparator)
        // 集合自带比较器对象
        // 如果类和集合都存在大小规则,默认使用集合自带的规则进行大小排序!!
        Set<Employee> employees1 = new TreeSet<>(new Comparator<Employee>() {
            @Override
            public int compare(Employee o1, Employee o2) {
                // o1比较者   o2被比较者
                // 如果程序员认为比较者大于被比较者 返回正数!
                // 如果程序员认为比较者小于被比较者 返回负数!
                // 如果程序员认为比较者等于被比较者 返回0!
                return o1.getAge() - o2.getAge();
            }
        });
        employees1.add(new Employee("播仔",6500.0,21));
        employees1.add(new Employee("播妞",7500.0,19));
        employees1.add(new Employee("乔治",4500.0,23));
        System.out.println(employees1);
    }
}
package com.itheima._04Set系列集合;

import java.util.Objects;

public class Apple {
    private String name;
    private double price ;
    private String color ;

    public Apple() {
    }

    public Apple(String name, double price, String color) {
        this.name = name;
        this.price = price;
        this.color = color;
    }

    // 只要两个对象的内容一样,equals比较的结果一定为true
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Apple apple = (Apple) o;
        return Double.compare(apple.price, price) == 0 &&
                Objects.equals(name, apple.name) &&
                Objects.equals(color, apple.color);
    }

    // 只要两个对象的内容一样返回的哈希值也要一样!true
    @Override
    public int hashCode() {
        // Apple a2 = new Apple("阿克苏",39.9 ,"青红色");
        // Apple a3 = new Apple("阿克苏",39.9 ,"青红色");
        //  a2.hashCode() == Objects.hash(阿克苏, 39.9, 青红色)
        //  a3.hashCode() == Objects.hash(阿克苏, 39.9, 青红色)
        return Objects.hash(name, price, color);
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return price
     */
    public double getPrice() {
        return price;
    }

    /**
     * 设置
     * @param price
     */
    public void setPrice(double price) {
        this.price = price;
    }

    /**
     * 获取
     * @return color
     */
    public String getColor() {
        return color;
    }

    /**
     * 设置
     * @param color
     */
    public void setColor(String color) {
        this.color = color;
    }

    public String toString() {
        return "Apple{name = " + name + ", price = " + price + ", color = " + color + "}";
    }
}
public class Employee implements Comparable<Employee>{
    private String name;
    private double salary;
    private int age;

    // 重写了比较方法。
    // e1.compareTo(o)
    // 比较者:this
    // 被比较者:o
    // 需求:按照年龄比较
    @Override
    public int compareTo(Employee o) {
        // 规则:Java规则
        // 如果程序员认为比较者大于被比较者 返回正数!
        // 如果程序员认为比较者小于被比较者 返回负数!
        // 如果程序员认为比较者等于被比较者 返回0!
//        if(this.age > o.age){
//            return 1;
//        }else if(this.age < o.age){
//            return -1;
//        }
//        return 0;
        return this.age - o.age;
    }

    public Employee() {
    }

    public Employee(String name, double salary, int age) {
        this.name = name;
        this.salary = salary;
        this.age = age;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return salary
     */
    public double getSalary() {
        return salary;
    }

    /**
     * 设置
     * @param salary
     */
    public void setSalary(double salary) {
        this.salary = salary;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "Employee{name = " + name + ", salary = " + salary + ", age = " + age + "}";
    }


}

Collections工具类的使用

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

/**
    目标:Collections工具类的使用。

    java.utils.Collections:是集合工具类
    Collections并不属于集合,是用来操作集合的工具类。
    Collections有几个常用的API:
         - public static <T> boolean addAll(Collection<? super T> c, T... elements)
             给集合对象批量添加元素!
         - public static void shuffle(List<?> list) :打乱集合顺序。
         - public static <T> void sort(List<T> list):将集合中元素按照默认规则排序。
         - public static <T> void sort(List<T> list,Comparator<? super T> ):将集合中元素按照指定规则排序。

 */
public class CollectionsDemo01 {
    public static void main(String[] args) {
        // 1.给集合批量添加元素
        Collection<String> names = new ArrayList<>();
        /**
         * 参数一:被添加元素的集合
         * 参数二:可变参数,一批元素
         */
        Collections.addAll(names,"曹操","贾乃亮","王宝强","陈羽凡");
        System.out.println(names);

        // 2.打乱集合的顺序:public static void shuffle(List<?> list)
        // 注意:只能打乱有序的List集合。
        List<String> newnames = new ArrayList<>();
        Collections.addAll(newnames,"曹操","贾乃亮","王宝强","陈羽凡");
        Collections.shuffle(newnames); // 打乱顺序
        System.out.println(newnames);

        // 3.public static <T> void sort(List<T> list):给List集合升序排序。
        List<Double> scores = new ArrayList<>();
        Collections.addAll(scores, 98.5, 66.5 , 59.5 , 66.5 , 99.5 );
        Collections.sort(scores); // 默认升序排序!
        System.out.println(scores);
    }
}

引用数据类型的排序

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
    目标:引用数据类型的排序。

    字符串按照首字符的编号升序排序!

    自定义类型的比较方法API:
         - public static <T> void sort(List<T> list):
               将集合中元素按照默认规则排序。
               对于自定义的引用类型的排序人家根本不知道怎么排,直接报错!
               如果希望自定义的引用类型排序不报错,可以给类提供比较规则:Comparable。

         - public static <T> void sort(List<T> list,Comparator<? super T> c):
                将集合中元素按照指定规则排序,自带比较器
                注意:如果类有比较规则,而这里有比较器,优先使用比较器。

 */
public class CollectionsDemo02 {
    public static void main(String[] args) {
        // 自定义类型如何排序!
        List<Orange> oranges = new ArrayList<>();
        Orange o1 = new Orange("红橘子",654.0 ,"贼便宜~");
        Orange o2 = new Orange("黄橘子",454.0 ,"贼便宜~");
        Orange o3 = new Orange("黄橘子",454.0 ,"贼便宜~");
        Orange o4 = new Orange("青橘子",456.0 ,"贼便宜~");
        Collections.addAll(oranges,o1,o2,o3,o4);
        Collections.sort(oranges); // 排序,按照类实现的比较规则进行排序!!
        System.out.println(oranges);


        List<Orange> oranges1 = new ArrayList<>();
        Orange o11 = new Orange("红橘子",654.0 ,"贼便宜~");
        Orange o22 = new Orange("黄橘子",454.0 ,"贼便宜~");
        Orange o33 = new Orange("黄橘子",454.0 ,"贼便宜~");
        Orange o44 = new Orange("青橘子",456.0 ,"贼便宜~");
        Collections.addAll(oranges1,o11,o22,o33,o44);
        // 优先用方法自带的比较器对象Comparator而不会用类的比较规则!!
        Collections.sort(oranges1, new Comparator<Orange>() {
            @Override
            public int compare(Orange o1, Orange o2) {
                if(o1.getWeight() > o2.getWeight()) return -1;
                if(o1.getWeight() < o2.getWeight()) return 1;
                return 0;
            }
        });
        System.out.println(oranges1);
    }
}

public class Orange implements Comparable {
    private String name;
    private double weight;
    private String price;

    public Orange() {
    }

    public Orange(String name, double weight, String price) {
        this.name = name;
        this.weight = weight;
        this.price = price;
    }

    public String getName() {
        return name;
    }

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

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Orange{" +
                "name='" + name + ''' +
                ", weight=" + weight +
                ", price='" + price + ''' +
                '}'+"n";
    }

    @Override
    public int compareTo(Object o) {
        Orange o2 = (Orange) o;
        // 集合会自动送入两个句子对象来比较!!
        // 认为o1 > o2返回正整数。
        // 认为o1 = o2返回0。
        // 认为o1 < o2返回负整数。
        if(this.weight > o2.weight) return 1;
        if(this.weight < o2.weight) return -1;
        return 0;
    }
}

斗地主游戏的案例开发

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

/**
    目标:斗地主游戏的案例开发。

    业务需求分析:
        斗地主的做牌,洗牌,发牌,排序(拓展知识), 看牌
        业务:总共有54张牌。
        点数: "3","4","5","6","7","8","9","10","J","Q","K","A","2"
        花色: "♠", "♥", "♣", "♦"
        大小王: "????" , ""
        点数分别要组合4种花色,大小王各一张。
        斗地主:发出51张牌,剩下3张作为底牌。

    功能:
        1.做牌。
        2.洗牌
        3.定义3个玩家。
        4.发牌。
        5.排序(拓展,了解)
        6.看牌。

    用面向对象设计案例:
        a.定义一个牌类,代表牌对象。 一个牌对象代表一张牌。
        b.定义一个集合存储54张牌,集合只需要一个(因为牌只需要一副)
 */
public class GameDemo {
    /** a.定义一个静态集合,存储54张牌对象,集合只需要一个 */
    public static final List<Card> ALL_CARDS = new ArrayList<>();

    /** b.做牌 */
    static {
        // 1.定义一个数组存储牌的点数,类型确定,个数确定请用数组存储!
        String[] numbers = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
        // 2.定义一个数组存储牌的花色,类型确定,个数确定请用数组存储!
        String[] colors = { "♠", "♥", "♣", "♦" };
        // 3.先遍历点数与四种花色组装成牌对象存入到集合中去
        for (String number : numbers) {
            // 遍历花色
            for (String color : colors) {
                // 创建一张牌对象封装点数和花色
                Card card = new Card(number , color);
                ALL_CARDS.add(card);
            }
        }
        // 4.单独加入大小王
        Collections.addAll(ALL_CARDS ,  new Card("","????") ,new Card("","????") );
        System.out.println("输出新牌:"+ALL_CARDS);
    }

    public static void main(String[] args) {

    }
}
// 牌类
public class Card {
    private String number;
    private String color;

    public Card() {
    }

    public Card(String number, String color) {
        this.number = number;
        this.color = color;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public String toString() {
        return number+color;
    }
}

Map集合

Map集合概述

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

/**
    目标:Map集合概述。

    Map集合是另一个集合体系。
    Collection是单值集合体系。

    Map集合是一种双列集合,每个元素包含两个值。
    Map集合的每个元素的格式:key=value(键值对元素)。
    Map集合也被称为“键值对集合”。

    Map集合的完整格式:{key1=value1 , key2=value2 , key3=value3 , ...}

    Map集合有啥用?
       1.Map集合存储的信息更加的具体丰富。
            Collection: ["苍老师","日本","女","动作演员",23,"广州"]
            Map : {name="苍老师" , jiaxiang=小日本 , sex="女" , age = 23 , addr=广州}

       2.Map集合很适合做购物车这样的系统。
            Map:  {娃娃=30 , huawei=1 , iphonex=1}

    注意:集合和泛型都只能支持引用数据类型,集合完全可以称为是对象容器,存储都是对象。

    Map集合的体系:
            Map<K , V>(接口,Map集合的祖宗类)
           /                      
          TreeMap<K , V>           HashMap<K , V>(实现类,经典的,用的最多)
                                     
                                      LinkedHashMap<K, V>(实现类)

    Map集合的特点:
        1.Map集合的特点都是由键决定的。
        2.Map集合的键是无序,不重复的,无索引的。
            Map集合后面重复的键对应的元素会覆盖前面的整个元素!
        3.Map集合的值无要求。
        4.Map集合的键值对都可以为null。

       HashMap:元素按照键是无序,不重复,无索引,值不做要求。
       LinkedHashMap:元素按照键是有序,不重复,无索引,值不做要求。
 */
public class MapDemo {
    public static void main(String[] args) {
        // 一行经典代码
        Map<String , Integer> maps = new HashMap<>();
        maps.put("娃娃",1);
        maps.put("huawei",10);
        maps.put("iphoneXS",2);
        maps.put(null , null );
        maps.put("娃娃",30);
        maps.put("特仑苏",2);
        System.out.println(maps);
    }
}

Map集合的常用API(重点中的重点)

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

/**
    目标:Map集合的常用API(重点中的重点)
     - public V put(K key, V value):  把指定的键与指定的值添加到Map集合中。
     - public V remove(Object key): 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
     - public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
     - public Set<K> keySet(): 获取Map集合中所有的键,存储到Set集合中。
     - public Set<Map.Entry<K,V>> entrySet(): 获取到Map集合中所有的键值对对象的集合(Set集合)。
     - public boolean containKey(Object key):判断该集合中是否有此键。
 */
public class MapDemo {
    public static void main(String[] args) {
        Map<String , Integer> maps = new HashMap<>();
        // 1.添加元素: 无序,不重复,无索引。
        maps.put("iphoneX",10);
        maps.put("娃娃",30);
        maps.put("iphoneX",100);//  Map集合后面重复的键对应的元素会覆盖前面重复的整个元素!
        maps.put("huawei",1000);
        maps.put("生活用品",10);
        maps.put("手表",10);
        // {huawei=1000, 手表=10, 生活用品=10, iphoneX=100, 娃娃=30}
        System.out.println(maps);

        // 2.清空集合
        //maps.clear();
        //System.out.println(maps);

        // 3.判断集合是否为空,为空返回true ,反之!
        System.out.println(maps.isEmpty());

        // 4.根据键获取对应值。
        //Integer value = maps.get("娃娃");
        //System.out.println(value);
        System.out.println(maps.get("娃娃"));

        // 5.根据键删除整个元素。(删除键会返回键的值)
        maps.remove("iphoneX");
        System.out.println(maps);

        // 6.判断是否包含某个键 ,包含返回true ,反之
        System.out.println(maps.containsKey("手表")); // true
        System.out.println(maps.containsKey(10)); // false

        // 7.判断是否包含某个值。
        System.out.println(maps.containsValue(1000)); // true
        System.out.println(maps.containsValue(10)); // true
        System.out.println(maps.containsValue("30")); // false 包含的是整数30不是字符串。

        // 8.获取全部键的集合:public Set<K> keySet()
        // Map集合的键是无序不重复的,所以返回的是一个Set集合。
        Set<String> keys = maps.keySet();
        for (String key : keys) {
            System.out.println(key);
        }

        // 9.获取全部值的集合:Collection<V> values();
        // Map集合的值是不做要求的,可能重复,所以值要用Collection集合接收!
        Collection<Integer> values = maps.values();
        for (Integer value : values) {
            System.out.println(value);
        }

        // 10.集合的大小
        System.out.println(maps.size());

        // 11.合并其他Map集合。(拓展)
        Map<String,Integer> maps2 = new HashMap<>();
        maps2.put("xiaoMi" , 1);
        maps2.put("????手机" , 10);
        maps2.put("手表" , 10000);
        maps.putAll(maps2); // 把Map集合maps2的数据全部倒入到maps集合中去
        System.out.println(maps);
    }
}

Map集合的遍历方式

“键找值”的方式遍历

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

/**
    目标:Map集合的遍历方式。

    Map集合的遍历方式有:3种。
        (1)“键找值”的方式遍历:先获取Map集合全部的键,再根据遍历键找值。
        (2)“键值对”的方式遍历:难度较大。
        (3)JDK 1.8开始之后的新技术:Lambda表达式。(暂时了解)

    a.“键找值”的方式遍历Map集合。
        1.先获取Map集合的全部键的Set集合。
        2.遍历键的Set集合,然后通过键找值。
    小结:
        代码简单,需要记住!

 */
public class MapDemo01 {
    public static void main(String[] args) {
        Map<String , Integer> maps = new HashMap<>();
        // 1.添加元素: 无序,不重复,无索引。
        maps.put("娃娃",30);
        maps.put("iphoneX",100);//  Map集合后面重复的键对应的元素会覆盖前面重复的整个元素!
        maps.put("huawei",1000);
        maps.put("生活用品",10);
        maps.put("手表",10);
        System.out.println(maps);
        // maps = {huawei=1000, 手表=10, 生活用品=10, iphoneX=100, 娃娃=30}

        // a.键找值方式遍历
        // 获取当前Map集合的全部键的集合 。
        Set<String> keys = maps.keySet();
        System.out.println(keys);
        // [huawei, 手表, 生活用品, iphoneX, 娃娃]
        //          key
        // b.通过遍历键然后通过键取对应的值
        for (String key : keys) {
            // 过键取对应的值
            Integer value = maps.get(key);
            System.out.println(key + "=" + value);
        }
    }
}

“键值对”的方式遍历

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

/**
    目标:Map集合的遍历方式。

    Map集合的遍历方式有:3种。
        (1)“键找值”的方式遍历:先获取Map集合全部的键,再根据键找值。
        (2)“键值对”的方式遍历:难度较大。
        (3)JDK 1.8开始之后的新技术:Lambda表达式。

    b.“键值对”的方式遍历:
        1.把Map集合转换成一个Set集合:Set<Map.Entry<K, V>> entrySet();
        2.此时键值对元素的类型就确定了,类型是键值对实体类型:Map.Entry<K, V>
        3.接下来就可以用foreach遍历这个Set集合,类型用Map.Entry<K, V>
 */
public class MapDemo02 {
    public static void main(String[] args) {
        Map<String , Integer> maps = new HashMap<>();
        // 1.添加元素: 无序,不重复,无索引。
        maps.put("娃娃",30);
        maps.put("iphoneX",100);//  Map集合后面重复的键对应的元素会覆盖前面重复的整个元素!
        maps.put("huawei",1000);
        maps.put("生活用品",10);
        maps.put("手表",10);
        System.out.println(maps);
        // maps = {huawei=1000, 手表=10, 生活用品=10, iphoneX=100, 娃娃=30}
        //
        /**
            “键值对”的方式遍历:更加面向对象的方式,代码复杂。

            “键值对”想把键值对当成一个整体遍历,也就是直接使用foreac遍历:
             for(被遍历集合的元素类型 变量:集合名称){

             }
             但是发现Map集合的键值对数据直接是没有元素类型的,foreach无法直接遍历Map集合。
                ????
             把Map集合通过代码Set<Map.Entry<K, V>> entrySet()转换成Set集合。
                ????
             Set<Map.Entry<String,Integer>> entries = maps.entrySet();
                ????
             entries = [(huawei=1000), (手表=10), (生活用品=10), (iphoneX=100), (娃娃=30) ]
             //                         entry
             此时键值对元素才能作为一个整体就有了类型。类型是 Map.Entry<String,Integer>实体类型
         */
        Set<Map.Entry<String,Integer>> entries = maps.entrySet();
        for (Map.Entry<String, Integer> entry : entries) {
             String key = entry.getKey();
             Integer value = entry.getValue();
             System.out.println(key + "=>" + value);
        }
    }
}

JDK 1.8开始之后的新技术:Lambda表达式

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

/**
    目标:Map集合的遍历方式。

    Map集合的遍历方式有:3种。
        (1)“键找值”的方式遍历:先获取Map集合全部的键,再根据键找值。
        (2)“键值对”的方式遍历:难度较大。
        (3)JDK 1.8开始之后的新技术:Lambda表达式。

    c.JDK 1.8开始之后的新技术:Lambda表达式。(暂时了解)

 */
public class MapDemo03 {
    public static void main(String[] args) {
        Map<String , Integer> maps = new HashMap<>();
        // 1.添加元素: 无序,不重复,无索引。
        maps.put("娃娃",30);
        maps.put("iphoneX",100);//  Map集合后面重复的键对应的元素会覆盖前面重复的整个元素!
        maps.put("huawei",1000);
        maps.put("生活用品",10);
        maps.put("手表",10);
        System.out.println(maps);
        // maps = {huawei=1000, 手表=10, 生活用品=10, iphoneX=100, 娃娃=30}

        maps.forEach((k , v) -> {
            System.out.println(k+"==>"+v);
        });
    }
}

Map集合存储自定义类型

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

/**
    目标:Map集合存储自定义类型;

    Map集合的键和值都可以存储自定义类型。

    小结:
        Map集合的键和值都可以存储自定义类型。
        如果希望Map集合认为自定义类型的键对象重复了,必须重写对象的hashCode()和equals()方法
 */
public class MapDemo01 {
    public static void main(String[] args) {
        Map<Orange,String> maps = new HashMap<>();
        Orange o1 = new Orange("黄橘子",20.3 , "贼便宜!");
        Orange o2 = new Orange("黑橘子",30.3 , "坏了");
        Orange o3 = new Orange("青橘子",34.3 , "9.9包邮");
        Orange o4 = new Orange("黄橘子",20.3 , "贼便宜!");

        maps.put(o1 , "江西n");
        maps.put(o2 , "赣州n");
        maps.put(o3 , "广州n");
        maps.put(o4 , "广西n");

        System.out.println(maps);
    }
}

import java.util.Objects;

public class Orange {
    private String name;
    private double weight;
    private String price;


    public Orange() {
    }

    public Orange(String name, double weight, String price) {
        this.name = name;
        this.weight = weight;
        this.price = price;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Orange orange = (Orange) o;
        return Double.compare(orange.weight, weight) == 0 &&
                Objects.equals(name, orange.name) &&
                Objects.equals(price, orange.price);
    }

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

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return weight
     */
    public double getWeight() {
        return weight;
    }

    /**
     * 设置
     * @param weight
     */
    public void setWeight(double weight) {
        this.weight = weight;
    }

    /**
     * 获取
     * @return price
     */
    public String getPrice() {
        return price;
    }

    /**
     * 设置
     * @param price
     */
    public void setPrice(String price) {
        this.price = price;
    }

    public String toString() {
        return "Orange{name = " + name + ", weight = " + weight + ", price = " + price + "}";
    }
}

LinkedHashMap的特点介绍

import java.util.*;

/**
    目标:LinkedHashMap的特点介绍。

    LinkedHashMap是HashMap的子类。
        -- 添加的元素按照键有序,不重复的。
    HashSet集合相当于是HashMap集合的键都不带值。
    LinkedHashSet集合相当于是LinkedHashMap集合的键都不带值。

    底层原理完全一样,都是基于哈希表按照键存储数据的,
    只是HashMap或者LinkedHashMap的键都多一个附属值。


    小结:
        HashMap集合是无序不重复的键值对集合。
        LinkedHashMap集合是有序不重复的键值对集合。
        他们都是基于哈希表存储数据,增删改查都很好。

 */
public class LinkedHashMapDemo {
    public static void main(String[] args) {
        Map<String , Integer> maps = new LinkedHashMap<>();
        maps.put("iphoneX",10);
        maps.put("娃娃",30);
        maps.put("iphoneX",100); // 依然是保留前面的位置,只是替换其值!
        maps.put("huawei",1000);
        maps.put("生活用品",10);
        maps.put("手表",10);
        System.out.println(maps);
    }
}

TreeMap集合应用

import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;

/**
    目标:TreeMap集合的特点和使用。

    TreeMap集合按照键是可排序不重复的键值对集合。(默认升序)
    TreeMap集合按照键排序的特点与TreeSet是完全一样的。
    小结:
        TreeMap集合和TreeSet集合都是排序不重复集合
        TreeSet集合的底层是基于TreeMap,只是键没有附属值而已。
        所以TreeMap集合指定大小规则有2种方式:
             a.直接为对象的类实现比较器规则接口Comparable,重写比较方法(拓展方式)
             b.直接为集合设置比较器Comparator对象,重写比较方法
 */
public class TreeMapDemo {
    public static void main(String[] args) {
        Map<Integer,String> maps = new TreeMap<>();
        maps.put(1000000,"张三");
        maps.put(1000000,"张三1");
        maps.put(10000,"李四");
        maps.put(10,"王五");
        maps.put(24244,"张麻子");
        System.out.println(maps);

        Map<Pig,String> pigs = new TreeMap<>();
        pigs.put(new Pig("????佩奇",99.5 , 500.0), "荷兰");
        pigs.put(new Pig("????乔治",99.4 , 605.0), "澳大利亚");
        pigs.put(new Pig("????野猪",199.4 , 305.0), "山上");
        pigs.put(new Pig("????野猪",199.4 , 305.0), "山上2");
        System.out.println(pigs);


        //  public TreeMap(Comparator<? super K> comparator)
        Map<Pig,String> pigs1 = new TreeMap<>(new Comparator<Pig>() {
            @Override
            public int compare(Pig p1, Pig p2) {
                return Double.compare(p1.getWeight() , p2.getWeight());
            }
        });
        pigs1.put(new Pig("????佩奇",99.5 , 500.0), "荷兰");
        pigs1.put(new Pig("????乔治",99.4 , 605.0), "澳大利亚");
        pigs1.put(new Pig("????野猪",199.4 , 305.0), "山上");
        pigs1.put(new Pig("????野猪",199.4 , 305.0), "山上2");
        System.out.println(pigs1);
    }
}
import java.util.Objects;

public class Pig implements Comparable{
    private String name;
    private double price ;
    private double weight;

    public Pig() {
    }

    public Pig(String name, double price, double weight) {
        this.name = name;
        this.price = price;
        this.weight = weight;
    }

    public String getName() {
        return name;
    }

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

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Pig pig = (Pig) o;
        return Double.compare(pig.price, price) == 0 &&
                Double.compare(pig.weight, weight) == 0 &&
                Objects.equals(name, pig.name);
    }

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

    @Override
    public String toString() {
        return "Pig{" +
                "name='" + name + ''' +
                ", price=" + price +
                ", weight=" + weight +
                '}';
    }

    // 比较者: this
    // 被比较者: o
    // 需求:按照价格排序!
    @Override
    public int compareTo(Object o) {
        // 浮点型的大小比较建议使用Java自己的API:
        // public static int compare(double d1, double d2)
        return  -Double.compare(this.price , ((Pig)o).price);
    }
}

Map集合练习

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
    目标:输出一个字符串中每个字符出现的次数。(经典面试题)

    分析:
        (1)键盘录入一个字符串。aabbccddaa123。
        (2)定义一个Map集合,键是每个字符,值是其出现的次数。 {a=4 , b=2 ,...}
        (3)遍历字符串中的每一个字符。
        (4)拿着这个字符去Map集合中看是否有这个字符键,有说明之前统计过,其值+1
            没有这个字符键,说明该字符是第一次统计,直接存入“该字符=1”

 */
public class MapDemo01 {
    public static void main(String[] args) {
        // (1)键盘录入一个字符串。aabbccddaa123。
        Scanner scanner = new Scanner(System.in);
        System.out.print("请您输入一个字符串:");
        String datas = scanner.nextLine();

        // (2)定义一个Map集合,键是每个字符,值是其出现的次数。
        Map<Character , Integer> infos = new HashMap<>(); // {a=2,b=2}

        // (3)遍历字符串中的每一个字符。
        // datas = aabbccddaa123
        for(int i = 0 ; i < datas.length() ; i++ ){
            // 取出当前索引的字符
            char ch = datas.charAt(i);
            // (4)拿着这个字符去Map集合中看是否有这个字符键,有说明之前统计过,其值+1
            //   没有这个字符键,说明该字符是第一次统计,直接存入“该字符=1”
            if(infos.containsKey(ch)){
                // 说明这个字符之前已经出现过,其值+1
                infos.put(ch , infos.get(ch) + 1);
            }else{
                // 说明这个字符第一次出现,直接存入 a=1
                infos.put(ch , 1);
            }
        }
        // (5)输出结果
        System.out.println("结果:"+infos);
    }
}

斗地主游戏洗牌发牌看牌

/**
    目标:斗地主游戏的案例开发-Map集合实现。

    业务需求分析:
        斗地主的做牌,洗牌,发牌,排序(拓展知识), 看牌
        业务:总共有54张牌。
        点数: "3","4","5","6","7","8","9","10","J","Q","K","A","2"
        花色: "♠", "♥", "♣", "♦"
        大小王: "????" , "????"
        点数分别要组合4种花色,大小王各一张。
        斗地主:发出51张牌,剩下3张作为底牌。

    功能:
        1.做牌。
        2.洗牌
        3.定义3个玩家。
        4.发牌。
        5.
        6.看牌。

    用面向对象设计案例:
        a.定义一个牌类,代表牌对象。 一个牌对象代表一张牌。
        b.定义一个集合存储54张牌,集合只需要一个(因为牌只需要一副)
                {card1=0 , card2=1, ......}
 */
public class GameDemo {
    /** 1.定义一个Map集合存储54张牌对象,键是牌对象,值是其大小 用于实现大小排序  */
    public static final Map<Card , Integer> ALL_CARDS_SIZE = new HashMap<>();
    // 真正存储54张牌对象的List集合,用于做牌,洗牌,发牌!
    public static final List<Card> ALL_CARDS = new ArrayList<>();
    /** 2.做牌:静态代码块初始化54张牌对象  */
    static {
        // 1.定义一个数组存储牌的点数,类型确定,个数确定请用数组存储!
        String[] numbers = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
        // 2.定义一个数组存储牌的花色,类型确定,个数确定请用数组存储!
        String[] colors = { "♠", "♥", "♣", "♦" };

        // 3.先遍历点数与四种花色组装成牌对象存入到集合中去
        int index = 0;
        for (String number : numbers) {
            // 遍历花色
            for (String color : colors) {
                // 创建一张牌对象封装点数和花色
                Card card = new Card(number , color);
                ALL_CARDS.add(card);
                ALL_CARDS_SIZE.put(card , index++);
            }
        }
        Card c1 = new Card("","????");
        Card c2 = new Card("", "????");

        ALL_CARDS.add(c1);
        ALL_CARDS.add(c2);
        ALL_CARDS_SIZE.put(c1 , index++);
        ALL_CARDS_SIZE.put(c2 , index++);
        System.out.println("新牌:"+ ALL_CARDS);
    }

    public static void main(String[] args) {
        /**
         c.洗牌(把新牌的牌顺序打乱)
         */
        Collections.shuffle(ALL_CARDS);
        System.out.println("洗牌后:"+ALL_CARDS);

        /**
         d.定义3个玩家。
         */
        List<Card> lingHuChong = new ArrayList<>();
        List<Card> jiuMoZhi = new ArrayList<>();
        List<Card> dongfangbubai = new ArrayList<>();

        /**
         e.发牌 依次发出51张牌出去。
         ALL_CARDS = [J♠, 5♠, 2♠, 9♣, 5♦, 4♠, Q♣, 6♥, 8♠, ......
         0   1   2   3   4    5   6   7   8   % 3(轮询的长度)
         */
        for(int i = 0 ; i < ALL_CARDS.size() - 3 ; i++ ){
            // 得到当前这张牌对象
            Card c = ALL_CARDS.get(i);
            // 判断这个牌发给谁
            if(i % 3 == 0 ){
                // 请令狐冲接牌
                lingHuChong.add(c);
            }else if(i % 3 == 1){
                // 请啊鸠接牌
                jiuMoZhi.add(c);
            }else if(i % 3 == 2){
                // 请阿东接牌
                dongfangbubai.add(c);
            }
        }

        /**
         * f.对牌进行排序(拓展,了解)
         */
        sortCards(lingHuChong);
        sortCards(jiuMoZhi);
        sortCards(dongfangbubai);

        /**
         g.看牌
         */
        System.out.println("令狐冲:"+lingHuChong);
        System.out.println("鸠摩智:"+jiuMoZhi);
        System.out.println("东方不败:"+dongfangbubai);
        //System.out.println("底牌:"+ALL_CARDS.get(53) +"-"+ALL_CARDS.get(52) + "-" +ALL_CARDS.get(51) );
        // 拓展: 截取集合的最后三张牌到一个新的List集合中去。
        List<Card> lastThreeCards = ALL_CARDS.subList(ALL_CARDS.size() -3 , ALL_CARDS.size());
        System.out.println("底牌:"+lastThreeCards);

    }

    /**
     对牌的List集合进行排序(降序排序)
     */
    private static void sortCards(List<Card> cards) {
        // cards = [ 3♦ , ????,  10♣ , 9♦ , 8♦ , J♠ , ...
        Collections.sort(cards, new Comparator<Card>() {
            @Override
            public int compare(Card o1, Card o2) {
                // o1   Q♦
                // o2   ????
                // 牌的大小就是当前牌在Map集合中的值存储的大小!
                return ALL_CARDS_SIZE.get(o2) - ALL_CARDS_SIZE.get(o1);
            }
        });
    }
}

package com.itheima._08斗地主游戏洗牌发牌看牌;

public class Card {
    private String number ;
    private String color ;

    public Card() {
    }

    public Card(String number, String color) {
        this.number = number;
        this.color = color;
    }

    /**
     * 获取
     * @return number
     */
    public String getNumber() {
        return number;
    }

    /**
     * 设置
     * @param number
     */
    public void setNumber(String number) {
        this.number = number;
    }

    /**
     * 获取
     * @return color
     */
    public String getColor() {
        return color;
    }

    /**
     * 设置
     * @param color
     */
    public void setColor(String color) {
        this.color = color;
    }

    public String toString() {
        return number+color;
    }
}

最后

以上就是殷勤白昼为你收集整理的集合--java常用APICollection集合List系列集合的使用Set系列集合Collections工具类的使用引用数据类型的排序斗地主游戏的案例开发Map集合的全部内容,希望文章能够帮你解决集合--java常用APICollection集合List系列集合的使用Set系列集合Collections工具类的使用引用数据类型的排序斗地主游戏的案例开发Map集合所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(55)

评论列表共有 0 条评论

立即
投稿
返回
顶部