Java-Collections、Map

目录

1.可变参数

2.Collections工具类

 

不同集合类型的排序方法比较

3.斗地主游戏

4.Map集合

4.1 Map集合概述

4.2 Map集合的常用方法

 4.3 Map集合的遍历方式

 4.4 Map集合案例—统计投票人数

4.5 HashMap

 4.6 LinkedHashMap

4.7 TreeMap

5.集合的嵌套


1.可变参数

import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        // 目标:掌握可变参数的使用。
        // 需求:求任意个整数数据的和.
       sum(); // 可以不传输参数
       sum(10); // 可以传一个参数
       sum(20, 15, 32,100); // 可以传多个参数
       sum(new int[]{10, 20, 30, 40}); // 可以传一个数组
    }

    // 作用:接收数据非常灵活
    // 注意事项:
    //    可变参数在形参列表中只能出现一个!
    //    可变参数必须放到形参列表的最后面!
    public static void sum(int...nums){
        // 本质:可变参数在方法内部本质就是一个数组。
        System.out.println("个数:" + nums.length);
        System.out.println("内容:" + Arrays.toString(nums));
    }
}

2.Collections工具类

package com.itheima.d2_collections;


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

/**
 * 目标:掌握Collections集合工具类的使用。
 */
public class CollectionsTest1 {
    public static void main(String[] args) {
        // 1、public static <T> boolean addAll(Collection<? super T> c, T...elements):为集合批量添加数据
        List<String> names = new ArrayList<>();
        Collections.addAll(names, "张无忌", "赵敏", "小昭", "殷素素");
        System.out.println(names);

        // 2、public static void shuffle(List<?> list):打乱List集合中的元素顺序
        Collections.shuffle(names);
        System.out.println(names);

        // 3、 public static <T> void sort(List<T> list):对List集合中的元素进行升序排序。
        List<Student> students = new ArrayList<>();
        Student s1 = new Student("赵敏", 19, 169.5);
        Student s2 = new Student("周芷若", 18, 171.5);
        Student s3 = new Student("周芷若", 18, 171.5);
        Student s4 = new Student("小昭", 17, 165.5);
        Collections.addAll(students, s1, s2, s3, s4);

        // 方式一:让对象的类实现Comparable接口,从写compare方法,指定大小比较规则
        Collections.sort(students);
        System.out.println(students);

        // 4、public static <T> void sort(List<T> list, Comparator<? super T> c):
        // 对List集合中元素,按照比较器对象指定的规则进行排序
        // 方式二:指定Comparator比较器对象,再指定比较规则。
        Collections.sort(students, ((o1, o2) -> Double.compare(o2.getHeight(), o1.getHeight())));
        System.out.println(students);
    }
}

 List集合是结合Collections工具类提供的sort方法进行比较,并不是自己带的比较器

有以下两种方式:

而TreeSet是自己带的比较器,并不是调用其他工具类的方法

天然有序,创建时指定排序规则

//        Set<Girl> set = new TreeSet<>(new Comparator<Girl>() {
//            @Override
//            public int compare(Girl o1, Girl o2) {
//                return Double.compare(o2.getHeight(),o1.getHeight());
//            }
//        });//排序,不重复,无索引
 
        //简化代码
Set<Girl> set = new TreeSet<>((o1, o2) -> Double.compare(o2.getHeight(),o1.getHeight()));

在Java中,对集合中的对象进行排序有两种方式

  • 实现比较器(Comparator),用匿名内部类来实现

eg:

public class Person implements Comparable<Person> {
    private int age;
    // 构造器、getter/setter略
    
    @Override
    public int compareTo(Person other) {
        return this.age - other.age; // 按年龄升序排序
    }
}
  • 让类实现Comparable接口来实现

eg:

// 按年龄降序排序
Comparator<Person> ageDescComparator = (p1, p2) -> p2.getAge() - p1.getAge();

不同集合类型的排序方法比较

  • List集合(如ArrayList、LinkedList)

1.自然排序(在对象类中实现Comparable<对象类型>)

List<Person> personList = new ArrayList<>();
// 添加元素...
Collections.sort(personList); // 按Person的compareTo方法排序

2.定制排序(用匿名内部类写Comparator)

// 按姓名长度升序排序
Collections.sort(personList, (p1, p2) -> p1.getName().length() - p2.getName().length());

// 多条件排序:先按年龄升序,年龄相同则按姓名降序
Collections.sort(personList, (p1, p2) -> {
    if (p1.getAge() != p2.getAge()) {
        return p1.getAge() - p2.getAge();
    } else {
        return p2.getName().compareTo(p1.getName());
    }
});
  • Array(数组)

1.基本类型数组(如int[ ]):直接使用Arrays.sort( )

int[] nums = {5, 2, 8, 1};
Arrays.sort(nums); // 结果:[1, 2, 5, 8]

 2.对象数组(如Person[ ]):

Person[] persons = new Person[3];
// 初始化数组...
Arrays.sort(persons, (p1, p2) -> p1.getName().compareTo(p2.getName())); // 按姓名升序
  • Set集合(如TreeSet、HashSet)

1.TreeSet:天然有序,创建时指定排血规则

// 按年龄升序排序
Set<Person> personSet = new TreeSet<>((p1, p2) -> p1.getAge() - p2.getAge());

// 或在创建时传入Comparator
Set<Person> personSet = new TreeSet<>(Comparator.comparing(Person::getAge));

 2.HashSet:无序,若需排序需先转为 List 再排序

Set<Person> hashSet = new HashSet<>();
// 添加元素...
List<Person> sortedList = hashSet.stream()
    .sorted(Comparator.comparing(Person::getAge))
    .collect(Collectors.toList());

3.斗地主游戏

Cards对象用来存储每一张牌的内容

package com.itheima.d3_collection_test;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

// Lombok : 使用注解简化get set 有参 无参构造器的写法
// IDEA >= 2022
// Lombok 是 30版本 不要用28
@Data
@NoArgsConstructor //无参构造器
@AllArgsConstructor //有参构造器
public class Card {
    private String number;
    private String color;
    private int size;

    @Override
    public String toString() {
        return number + color;
    }
}
package com.itheima.d3_collection_test;

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

//房间对象
public class Room {
    //1.准备一副牌
    private ArrayList<Card> allCards = new ArrayList<>();
    //2.初始化54张牌,用实例代码块初始化,创建房间对象时,为allCards集合初始化54张牌
    {
        //3.准备点数 : 个数确定,类型确定
        String[] numbers = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
        //4.准备花色 : 个数确定,类型确定
        String[] colors = {"♠", "♥", "♣", "♦"};
        //5.准备组装每一张牌对象
        int size = 0;
        for (String number : numbers) {
            size++;
            for (String color : colors) {
                //6.创建对象封装这张牌数据
                Card c = new Card(number,color,size);
                //7.加入到集合中去
                allCards.add(c);
            }
        }
        //8.单独加入大小王
        allCards.add(new Card("","小王",++size));
        allCards.add(new Card("","大王",++size));
        System.out.println("新牌是:" + allCards);

    }

    public void start() {
        //9.洗牌
        Collections.shuffle(allCards);
        System.out.println("洗牌后" + allCards);
        //10.发牌
        //定义三个玩家。
        List<Card> lhc = new ArrayList<>();
        List<Card> ryy = new ArrayList<>();
        List<Card> dfbb = new ArrayList<>();

        //发出去51张
        //allCards = [9♥, K♦, 8♣, 2♦, Q♦, 9♦, 8♠, 6♠, 3♠, 7♠, 4♥
        //            0    1   2   3   4   5   6...轮询算法
        for (int i = 0; i < allCards.size() - 3; i++) {
            Card c = allCards.get(i);
            if(i % 3 == 0){
                 //请lhc接牌
                lhc.add(c);
            } else if (i % 3 == 1) {
                //请ryy接牌
                ryy.add(c);
            }else if (i % 3 == 2){
                //请dfbb接牌
                dfbb.add(c);
            }
        }

        //拿到最后三张底牌:
        //subList截取子集合到新的集合中去
        List<Card> lastThreeCards = allCards.subList(allCards.size() - 3 ,allCards.size());
        //抢地主
        ryy.addAll(lastThreeCards);

        //11.对牌排序
        sortCards(lhc);
        sortCards(ryy);
        sortCards(dfbb);

        //12.看牌
        System.out.println("lhc" + lhc);
        System.out.println("ryy" + ryy);
        System.out.println("dfbb" + dfbb);
    }

    private void sortCards(List<Card> Cards) {
        Collections.sort(Cards, new Comparator<Card>() {
            @Override
            public int compare(Card o1, Card o2) {
                return o2.getSize() - o1.getSize();
            }
        });
    }
}
package com.itheima.d3_collection_test;

public class Test {
    public static void main(String[] args) {
        // 目标:完成斗地主案例的实现。'
        // "3","4","5","6","7","8","9","10","J","Q","K","A","2"
        // "♠", "♥", "♣", "♦"
        // 1、每张牌是一个对象,设计一个牌类。
        // 2、设计一个房间类,用于创建房间对象,开启游戏。
        Room r= new Room();
        r.start();
    }
}

4.Map集合

4.1 Map集合概述

 注意!!!集合和泛型都不支持基本类型,可以写包装类

package com.itheima.d4_map;

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

public class MapDemo1 {
    public static void main(String[] args) {
        // 目标:掌握Map集合的特点。
        // Map体系整体特点:HashMap : 按照键,无序,不重复,无索引。值不做要求,键和值都可以是null
        Map<String, Integer> map = new HashMap<>(); // 多态 一行经典代码
        map.put("华为手表", 31);
        map.put("iphone15", 1);
        map.put("mete60", 10);
        map.put("Java入门到跑路", 2);
        map.put("iphone15", 31); // 后面重复的键会覆盖前面整个数据!
        map.put("娃娃", 1);
        map.put("雨伞", 10);
        map.put(null, null);
        // {Java入门到跑路=2, null=null, iphone15=31, 雨伞=10, mete60=10, 华为手表=31, 娃娃=1}
        System.out.println(map);
    }
}

 Map集合(如HashMap)的“无序”是指元素的存储顺序与插入顺序不一致:

  • 当向 Map 中添加键值对时,元素的存储位置由键的哈希值决定(通过哈希函数计算存储位置),而非插入顺序。
  • 遍历时,元素的输出顺序可能与插入顺序不同,甚至多次遍历的顺序也可能不一致。

4.2 Map集合的常用方法

为什么要先学习Map的常用方法?

  • Map是双列集合的祖宗,它的功能是全部双列集合都可以继承过来使用

package com.itheima.d4_map;

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

public class MapDemo2 {
    public static void main(String[] args) {
        // 目标:掌握Map集合的常用API(重点)
        Map<String, Integer> map = new HashMap<>();
        map.put("手表" ,2);
        map.put("iphone" ,31);
        map.put("huawei" ,365);
        map.put("iphone" ,1);
        map.put("娃娃", 31);
        map.put("Java入门",1);
        map.put(null,null);
        System.out.println(map);
        // map = {null=null, 手表=2, huawei=365, Java入门=1, 娃娃=31, iphone=1}

        // 1、获取集合的大小(元素个数)
        System.out.println(map.size()); // 6

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

        // 3、判断集合是否为空
        System.out.println(map.isEmpty());

        // 4、根据键获取对应的值(重点)
        System.out.println(map.get("手表"));
        System.out.println(map.get("手表2"));  // 如果没有这个键,返回null

        // 5、根据键删除整个数据,返回删除数据对应的值。(重点)
        System.out.println(map.remove("娃娃"));
        System.out.println(map);

        // 6、判断是否包含某个键(重点)'
        // map = {null=null, 手表=2, huawei=365, Java入门=1,iphone=1}
        System.out.println(map.containsKey("娃娃")); // false
        System.out.println(map.containsKey("huawei")); // true
        System.out.println(map.containsKey(null)); // true
        System.out.println(map.containsKey("手表2")); // false

        // 7、判断是否包含某个值
        // map = {null=null, 手表=2, huawei=365, Java入门=1,iphone=1}
        System.out.println(map.containsValue(1)); // true
        System.out.println(map.containsValue(365)); // true
        System.out.println(map.containsValue("1")); // false

        // 8、获取Map集合的全部键,到一个Set集合中返回的
        // map = {null=null, 手表=2, huawei=365, Java入门=1,iphone=1}
        // public Set<K> keySet():
        Set<String> keys = map.keySet();
        for (String key : keys) {
            System.out.println(key);
        }

        // 9、获取Map集合的全部值:到一个Collection集合中返回的。
        Collection<Integer> values = map.values();
        for (Integer value : values) {
            System.out.println(value);
        }
    }
}

 4.3 Map集合的遍历方式

package com.itheima.d5_map_travesal;

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

public class MapDemo1 {
    public static void main(String[] args) {
        // 目标:掌握Map集合的遍历方式一:键找值
        Map<String, Integer> map = new HashMap<>(); // 一行经典代码
        map.put("iphone", 6);
        map.put("小米", 3);
        map.put("huawei", 3);
        map.put("诺基亚", 31);
        System.out.println(map);  // {huawei=3, 诺基亚=31, iphone=6, 小米=3}

        // 1、获取map集合的全部键
        Set<String> keys = map.keySet();
        // 2、根据键提取值
        for (String key : keys) {
            Integer value = map.get(key);
            System.out.println(key + "====>" + value);
        }

    }
}

 

package com.itheima.d5_map_travesal;

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

public class MapDemo2 {
    public static void main(String[] args) {
        // 目标:掌握Map集合的遍历方式二:键值对遍历(难度大点)
        Map<String, Integer> map = new HashMap<>();
        map.put("蜘蛛精", 1000);
        map.put("小龙女", 23);
        map.put("木婉清", 31);
        map.put("黄蓉", 35);
        System.out.println(map);
        // map = {蜘蛛精=1000, 小龙女=23, 黄蓉=35, 木婉清=31}

        // 1、一开始是想通过增强for直接遍历Map集合,但是无法遍历,因为键值对直接来看是不存在数据类型的。
//        for (元素类型 变量: map){
//
//        }

        // 2、调用Map集合的一个方法,把Map集合转换成Set集合来遍历
        /**
         *    map = {蜘蛛精=1000, 小龙女=23, 黄蓉=35, 木婉清=31}
         *    ↓
         *    map.entrySet()
         *    ↓
         *    Set<Map.Entry<String, Integer>> entries = [(蜘蛛精=1000), (小龙女=23), (黄蓉=35), (木婉清=31)]
         *                                                    entry
         */
        Set<Map.Entry<String, Integer>> entries = map.entrySet();
        for (Map.Entry<String, Integer> entry : entries) {
            String key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println(key + " ===> " + value);
        }
    }

 

package com.itheima.d5_map_travesal;

import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;

public class MapDemo3 {
    public static void main(String[] args) {
        // 目标:掌握Map集合的遍历方式三:Lambda
        Map<String, Integer> map = new HashMap<>();
        map.put("蜘蛛精", 1000);
        map.put("小龙女", 23);
        map.put("木婉清", 31);
        map.put("黄蓉", 35);
        System.out.println(map);
        // map = {蜘蛛精=1000, 小龙女=23, 黄蓉=35, 木婉清=31}

        map.forEach(new BiConsumer<String, Integer>() {
            @Override
            public void accept(String key, Integer value) {
                System.out.println(key + "===>" + value);
            }
        });

        map.forEach((key, value) -> {
            System.out.println(key + "===>" + value);
        });
    }
}

 4.4 Map集合案例—统计投票人数

需要做一 一对应的数据时,我们就优先考虑用Map集合来做

package com.itheima.d5_map_travesal;

import java.util.*;

public class MapTest5 {
    //需求:统计各个景点想去的人数
    public static void main(String[] args) {
        //1.把80个学生可选择的景点造出来
        String[] locations = {"玉龙雪山", "伶仃岛", "三亚", "泰国"};

        //2.定义一个List集合,来存储80个学生所挑选的想去的景点
        List<String> data = new ArrayList<>();
        //3.用随机数来随机数组里的景点,模拟80个学生进行选择
        Random r = new Random();
        //4.遍历80个学生,每一次都像List集合中存入想去的景点
        for (int i = 0; i < 80; i++) {
            data.add(locations[r.nextInt(locations.length)]);
        }
        System.out.println(data);

        //5.定义一个Map集合,键存储景点,值存储想去的人数
        Map<String, Integer> map = new HashMap<>();
        //6.遍历data,向map中存入数据
        for (String s : data) {
            //7.判断map中存在data当前所遍历的景点键
            if (map.containsKey(s)) {
                //如果之前出现过,map值+1
                map.put(s,map.get(s) + 1);
            }else {
                //第一次添加
                map.put(s,1);
            }
        }

        map.forEach((s,n) -> System.out.println(s + "选择的人数是:" + n));
        }
}

4.5 HashMap

HasSet的底层就是基于HashMap实现的,HashSet中只展示键,不展示值

每次扩容为原来的两倍,关于哈希表的具体解释可以参考JAVA-异常、Collection-优快云博客

package com.itheima.d6_map_impl;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data // Data自带了无参 + get + set + toString + hashCode + equals
@NoArgsConstructor
@AllArgsConstructor//写了有参之后data中的无参就会消失,所以写了有参就必须写无参
public class Movie implements Comparable<Movie>{
    private String name;
    private double score;
    private String actor;

}
package com.itheima.d6_map_impl;


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

public class MapTest1 {
    public static void main(String[] args) {
        // 目标:掌握Map集合(键)去重复的机制。
        Map<Movie, String> map = new HashMap<>();
        map.put(new Movie("摔跤吧,爸爸", 9.5, "阿米尔汗"), "19:00");
        map.put(new Movie("三傻宝莱坞", 8.5, "阿米尔汗2"), "20:50");
        map.put(new Movie("三傻宝莱坞", 8.5, "阿米尔汗2"), "21:50");
        map.put(new Movie("阿甘正传", 7.5, "汤姆汉克斯"), "21:00");
        System.out.println(map);

    }
}

 4.6 LinkedHashMap

类似于LinkedHashSet

4.7 TreeMap

package com.itheima.d6_map_impl;

import java.util.*;

public class MapTest3 {
    public static void main(String[] args) {
        // 目标:了解TreeMap集合:按照你键升序排序,不重复,无索引。
        // 方式二:TreeMap集合肯定可以自带比较器对象指定比较规则
        Map<Movie, String> map = new TreeMap<>((m1, m2) -> Double.compare(m2.getScore(), m1.getScore()));
        // 方式一:Movie类实现Comparable接口指定比较规则
        map.put(new Movie("摔跤吧,爸爸", 9.5, "阿米尔汗"), "19:00");
        map.put(new Movie("三傻宝莱坞", 8.5, "阿米尔汗2"), "20:50");
        map.put(new Movie("三傻宝莱坞", 8.5, "阿米尔汗2"), "21:50");
        map.put(new Movie("阿甘正传", 7.5, "汤姆汉克斯"), "21:00");
        System.out.println(map);
    }
}
package com.itheima.d6_map_impl;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data // Data自带了无参 + get + set + toString + hashCode + equals
@NoArgsConstructor
@AllArgsConstructor//写了有参之后data中的无参就会消失,所以写了有参就必须写无参
public class Movie implements Comparable<Movie>{
    private String name;
    private double score;
    private String actor;

    @Override
    public int compareTo(Movie o) {
        return Double.compare(this.score, o.score);
    }
}

5.集合的嵌套

package com.itheima.d6_map_impl;

import java.util.*;

public class MapTest4 {
    public static void main(String[] args) {
        // 目标:掌握集合的嵌套(重点)
        // 1、定义一个Map集合存储全部省份和城市信息。
        Map<String, List<String>> provinces = new HashMap<>();

        // 2、存入省份信息
        List<String> cities1 = new ArrayList<>();
        Collections.addAll(cities1, "南京市", "扬州市", "苏州市", "无锡市", "常州市");
        provinces.put("江苏省", cities1);

        List<String> cities2 = new ArrayList<>();
        Collections.addAll(cities2, "武汉市", "襄阳市", "孝感市", "十堰市", "宜昌市");
        provinces.put("湖北省", cities2);

        List<String> cities3 = new ArrayList<>();
        Collections.addAll(cities3, "石家庄市", "唐山市", "邢台市", "保定市", "张家口市");
        provinces.put("河北省", cities3);

        System.out.println(provinces);

        List<String> hbcities = provinces.get("湖北省");
        for (String hbcity : hbcities) {
            System.out.println(hbcity);
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值