0
点赞
收藏
分享

微信扫一扫

学习Java第14天

卿卿如梦 2022-03-30 阅读 76
java

Set系列集合、Map集合体系

Set系列集合特点:

无序:存取顺序不一致

不重复:可以去除重复

无索引:没有带索引的方法,所以不能使用普遍for循环遍历,也不能通过索引来获取元素

Set集合实现类特点:

HashSet:无序,不重复,无索引

LinkedHashSet:有序,不重复,无索引

TreeSet:排序、不重复、无索引

Set集合的功能基本上与Collection的API一致

package com.itheima.d1_set;
import java.util.HashSet;
import java.util.Set;
public class SetDemo1 {
    public static void main(String[] args) {
        //查看Set系列集合的特点:HashSet LinkedHashSet TreeSet
        //无序,不重复,无索引
        Set<String> sets=new HashSet<>();
        sets.add("MySql");
        sets.add("MySql");
        sets.add("Java");
        sets.add("Java");
        sets.add("HTML");
        sets.add("HTML");
        sets.add("SpringBoot");
        sets.add("SpringBoot");
        System.out.println(sets);//[Java, MySql, HTML, SpringBoot]
    }
}
package com.itheima.d1_set;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
public class SetDemo1 {
    public static void main(String[] args) {
        //查看Set系列集合的特点:HashSet LinkedHashSet TreeSet
        //无序,不重复,无索引
        Set<String> sets=new LinkedHashSet<>();
        sets.add("MySql");
        sets.add("MySql");
        sets.add("Java");
        sets.add("Java");
        sets.add("HTML");
        sets.add("HTML");
        sets.add("SpringBoot");
        sets.add("SpringBoot");
        System.out.println(sets);//[MySql, Java, HTML, SpringBoot]
    }
}
Set系列集合的特点:

无序、不重复、无索引

Set集合的实现类特点

HashSet无序,不重复,无索引

LinkedHashSet:有序,不重复,无索引

TreeSet:可排序,不重复,无索引

HashSet底层原理:

HashSet集合底层采取哈希表存储的数据

哈希表是一种对于增删改查数据性能都较好的结构

哈希表的组成:

JDK8之前,底层使用数组+链表组成

JDK8之后,底层采用数组+链表+红黑树组成

在了解哈希表之前需要先理解哈希值的概念

哈希值:

是JDK根据对象的地址,按照某种规则算出来的int类型的数值

Object类型的API:

public int hashCode():返回对象的哈希值

对象的哈希值特点:

同一个对象多次调用hashCode()方法返回的哈希值是相同的

默认情况下,不同对象的哈希值是不同的

 

 

 

 

 

 

 

package com.itheima.d1_set;
import java.util.Set;
import java.util.TreeSet;
/*目标:观察TreeSet对于有值特性的数据如和排序
* 学会使用自定以类型的对象进行指定规则排序*/
public class SetDemo4 {
    public static void main(String[] args) {
        Set<Integer> sets=new TreeSet<>();//不重复 无索引 可排序
        sets.add(23);
        sets.add(78);
        sets.add(19);
        sets.add(36);
        System.out.println(sets);//19 23 36 78

        Set<String> sets1=new TreeSet<>();//不重复 无索引 可排序
        sets1.add("cba");//根据首字母在ASCLL码表排序的
        sets1.add("Java");
        sets1.add("Abc");
        sets1.add("bcs");
        System.out.println(sets1);//Abc bcs cba
    }
}

package com.itheima.d1_set;

public class Apple implements Comparable<Apple>{
    private String name;
    private String color;
    private double price;
    private int weight;

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

    public Apple() {
    }

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

    public String getName() {
        return name;
    }

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

    public String getColor() {
        return color;
    }

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

    public double getPrice() {
        return price;
    }

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

    public int getWeight() {
        return weight;
    }

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

    /**
     * 方法一:类自定义比较规则
     * @param o
     * @return
     */
    @Override
    public int compareTo(Apple o) {
        //按照重量进行比较的
        return this.weight-o.weight>=0?1:-1;
    }
}

 

package com.itheima.d1_set;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
/*目标:观察TreeSet对于有值特性的数据如和排序
* 学会使用自定以类型的对象进行指定规则排序*/
public class SetDemo4 {
    public static void main(String[] args) {
        Set<Integer> sets=new TreeSet<>();//不重复 无索引 可排序
        sets.add(23);
        sets.add(78);
        sets.add(19);
        sets.add(36);
        System.out.println(sets);//19 23 36 78

        Set<String> sets1=new TreeSet<>();//不重复 无索引 可排序
        sets1.add("cba");//根据首字母在ASCLL码表排序的
        sets1.add("Java");
        sets1.add("Abc");
        sets1.add("bcs");
        System.out.println(sets1);//Abc Java bcs cba
        System.out.println("---------------");
        Set<Apple> apples=new TreeSet<>(new Comparator<Apple>() {
            @Override
            public int compare(Apple o1, Apple o2) {
                //return o1.getWeight()-o2.getWeight();升序
                //return o2.getWeight()-o2.getWeight();//降序
                //注意:浮点型建议直接使用Double.compare进行比较
                return Double.compare(o1.getPrice(),o2.getPrice());
            }
        });      
Set<Apple> apples=new TreeSet<>((o1,o2) -> Double.compare(o2.getPrice(), o1.getPrice()) );
        apples.add(new Apple("红富士","红色",9.9,500));
        apples.add(new Apple("青苹果","青色",15.9,400));
        apples.add(new Apple("黄苹果","黄色",17,450));
        apples.add(new Apple("绿苹果","绿色",29.7,400));
        System.out.println(apples);//[Apple{name='青苹果', color='青色',
        // price=15.9, weight=300}, Apple{name='绿苹果', color='绿色',
        // price=29.7, weight=400}, Apple{name='黄苹果', color='黄色',
        // price=17.0,
        // weight=450}, Apple{name='红富士', color='红色', price=9.9,
        // weight=500}]
    }
}

 TreeSet集合的特点是怎样的?

可排序,不重复,无索引

底层基于红黑树实现排序,增删改查性能较好

TreeSet集合自定义排序桂希恩有几种方式?

2种

类实现Comparable接口,重写比较规则

集合自定义Comparable比较器对象,重写比较规则

可变参数:

可变参数用在形参中可以接受多个数据

可变参数的格式:数据类型...参数名称

可变参数的作用:

传输参数非常灵活,方便。可以不传参数,可以传输1个或者多个,也可以传输一个数组

 

斗地主游戏:

package com.itheima.d3_coolection_test;

public class Card {
    private String size;
    private String color;
    private int index;

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

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

    public Card() {
    }

    public Card(String size, String color,int index) {
        this.size = size;
        this.color = color;
        this.index=index;
    }

    public String getSize() {
        return size;
    }

    public void setSize(String size) {
        this.size = size;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}
package com.itheima.d3_coolection_test;

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

public class GameDemo {
    /*定义一个静态的集合存储54张牌对象*/
    public static List<Card> allCards=new ArrayList<>();
    //作牌:定义静态代码块初始化牌的数据
    static{
        //3.定义点数:小数确定,类型确定,使用数据
        String[] sizes={"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
        //定义花色,个数确定,类型确定,使用数组
        String[] colors={"♦","♥","♣","♠"};
        //综合点数和花色
        int index=0;
        for(String size:sizes){
            index++;
            for(String color:colors){
                //封装成一个牌对象
                Card c=new Card(size,color,index);
                //存入到集合容器中去
                allCards.add(c);
            }
        }
        //大小王存入到集合对象中去
        Card c1=new Card("","🃏",++index);
        Card c2=new Card("","🃏",++index);
        Collections.addAll(allCards,c1,c2);
        System.out.println("新牌:"+allCards);
    }
    public static void main(String[] args) {
        //9.洗牌
        Collections.shuffle(allCards);
        System.out.println("洗牌后:"+allCards);
        //10:发牌:定义三个玩家,每个玩家的拍色也是一个集合容器
        List<Card> linghuchong=new ArrayList<>();
        List<Card> jiumozhi=new ArrayList<>();
        List<Card> renyingying=new ArrayList<>();
        //11.开始发牌,从牌集合中发出51张牌给三个玩家,剩余3张作为底牌
        for (int i = 0; i < allCards.size()-3; i++) {
            //先拿到当前牌对象
            Card c=allCards.get(i);
            if(i%3==0){
                linghuchong.add(c);
            }else if(i%3==1){
                jiumozhi.add(c);
            }else if(i%3==2){
                renyingying.add(c);
            }
        }
        //拿到最后三张底牌
        List<Card> lastThreeCards=allCards.subList(allCards.size()-3,allCards.size());
        //给玩家的牌排序(从大到小  可以自己先试一试)
        sortCards(linghuchong);
        sortCards(jiumozhi);
        sortCards(renyingying);
        //输出玩家的牌
        System.out.println("啊冲:"+linghuchong);
        System.out.println("啊久:"+jiumozhi);
        System.out.println("盈盈:"+renyingying);
        System.out.println("三张底牌:"+lastThreeCards);
    }
    //给牌排序
    private static void sortCards(List<Card> cards) {
        Collections.sort(cards, new Comparator<Card>() {
            @Override
            public int compare(Card o1, Card o2) {
                return o2.getIndex()- o1.getIndex();
            }
        });
    }
}

 Map集合概述和使用:

Map集合是一种双列集合,每个元素包含两个数据

Map集合的每个元素的格式:key=value(键值对元素)

Map集合也称为"键值对集合"

Map集合整体格式:

Collection集合的格式:[元素1,元素2,元素3...]

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

Map集合的使用场景之一:

 购物车提供的四个商品和购买的数量在后台需要容器存储

每个商品对象都一一对应一个购买数量

把商品对象看成是Map集合的键,购买数量看成Map集合的值

{商品1=2,商品2=3,商品3=4,商品4=3}

Map集合是什么?使用场景是什么样的?

Map集合是键值对集合

Map集合非常适合做类购物车这样的业务场景

Map集合体系特点:

Map集合的键无序,不重复的  Map集合的值不做要求可以重复

Map集合体系特点:

Map集合的特点都是由键决定的

Map集合的键是无序的,不重复的,无索引的,只可以不做要求(可以重复)

Map集合后面重复的键对应的值会覆盖前面重复的键

Map集合的键值对都可以为null

Map集合实现类特点:

HashMap:元素按照键是无序,不重复,无索引,值不做要求(与Map体系一致)

package com.itheima.d5_map;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
//识别Map体系的特点:按照键无序,不重复,无索引,值不做要求
public class MapDemo1 {
    public static void main(String[] args) {
        //创建一个Map集合对象,maps添加的方式是put
        //Map<String, Integer> maps = new HashMap<>();
        Map<String,Integer> maps=new LinkedHashMap<>();
        maps.put("鸿星尔克",3);
        maps.put("枸杞",1);
        maps.put("Java",100);
        maps.put("枸杞",100);
        maps.put(null,null);//如果前面的键与后面的键相同,那么后面的值将覆盖前面的值
        System.out.println(maps);//{鸿星尔克=3, 枸杞=100, Java=100, null=null}
    }
}

 Map集合的特点:

HashMap:元素按照键是无序,不重复,无索引,值不做要求(与Map体系一致)

LinkedHashMap:元素按照是有序,不重复,无索引,值不做要求

TreeMap:元素按照键是排序,不重复的,无索引的,值不做要求

Map集合:

Map是双列集合的祖宗接口,他的功能是全部双列集合都可以继承使用的

 

package com.itheima.d5_map;
import java.util.*;

public class MapDemo2 {
    public static void main(String[] args) {
        //1.添加元素:无序,不重复,无索引
        Map<String, Integer> maps = new HashMap<>();
        maps.put("iphoneX",10);//Map集合后面重复的键对于的元素会
                                // 覆盖前面重复的个数
        maps.put("娃娃",31);
        maps.put("iphoneX",100);
        maps.put("huawei",100);
        maps.put("生活用品",10);
        maps.put("手表",102);
        System.out.println(maps);
        //2.清空集合
        //maps.clear();
        //System.out.println(maps);
        //3.判断集合是否为空,为空返回true,反之
        //System.out.println(maps.isEmpty());
        //4.根据键获取对应值:public V get(Object key)
        Integer key=maps.get("huawei");
        System.out.println(key);
        System.out.println(maps.get("生活用品"));
        System.out.println(maps.get("你好"));
         //5.根据键删除整个元素(删除键会返回键的值)
        System.out.println(maps.remove("iphoneX"));
        System.out.println(maps);
        //6.判断是否包含某个键,包含返回true.反之
        System.out.println(maps.containsKey("娃娃"));
        System.out.println(maps.containsKey("iphoneX"));
        //7.判断是否包含某个值
        System.out.println(maps.containsValue(10));
        System.out.println(maps.containsValue(100));
        //8.获取全部键的集合,public Set<K> keySet()
        Set<String> keys=maps.keySet();
        System.out.println(keys);
        System.out.println("-----------------");
        //9.获取全部值的集合,Collection<V> values
        Collection<Integer> values=maps.values();
        System.out.println(values);
        //10.集合的大小
        System.out.println(maps.size());
        //11.合并其他Map集合(拓展)
        Map<String,Integer> map1=new HashMap<>();
        map1.put("java1",1);
        map1.put("java2",100);
        map1.put("java2",101);
        Map<String, Integer> map2 = new HashMap<>();
        map2.put("java2",1);
        map2.put("java3",100);
        map1.putAll(map2);
        System.out.println(map1);
        System.out.println(map2);
    }
}
Map集合的遍历方式一:键找值

 

package com.itheima.d5_map;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MapDemo3 {
    public static void main(String[] args) {
        Map<String,Integer> maps=new HashMap<>();
        maps.put("娃娃",30);
        maps.put("iphoneX",100);
        maps.put("huiwei",1000);
        maps.put("生活用品",10);
        maps.put("手表",10);
        System.out.println(maps);
        //{手表=10, 生活用品=10, huiwei=1000, iphoneX=100, 娃娃=30}
        //1.键找值:第一步:先拿到集合的全部键
        Set<String> keys=maps.keySet();
        //2.第二步:遍历每个键,根据键提取值
        for(String key:keys){
            //调用maps中的get方法得到键
            int value=maps.get(key);
            System.out.println(key+"==>"+value);
        }
    }
}

遍历Map集合方式二:键值对

先把Map集合转换成Set集合,Set集合中每个元素都是键值对实体类型了

遍历Set集合,然后提取键以及提取值

package com.itheima.d5_map;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo4 {
    public static void main(String[] args) {
        Map<String,Integer> maps=new HashMap<>();
        maps.put("娃娃",30);
        maps.put("iphoneX",100);
        maps.put("huawei",88);
        maps.put("生活用品",10);
        maps.put("手表",10);
        System.out.println(maps);
        //Set<Map.Entry<String,Integer>> entries=maps.entrySet();
        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)
        }
    }                
}

Map集合的遍历方式三:lambda

得益于JDK8开始的新技术Lambda表达式。提供了一种更简单,更直接的遍历集合的方式

Map结合Lambda遍历的API

default void forEach(BiConsumer<? super K,? super V>action>)   结合lambda遍历Map集合

package com.itheima.d6_map_test;

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

//需求:统计投票人数
public class MapTest1 {
    public static void main(String[] args) {
        //1.把80个学生选择的数据拿进来
        String[] selects={"A","B","C","D"};
        //定义一个StringBuilder的对象
        StringBuilder sb=new StringBuilder();
        //获取一个随机数对象
        Random ra = new Random();
        //定义一个循环
        for (int i = 0; i < 80; i++) {
            //用StringBuilder的对象名添加学生,selects添加的数组值为随机数
            sb.append(selects[ra.nextInt(selects.length)]);
        }
        System.out.println(sb);
        //定义一个Map集合记录最终统计的结果 A=30
        Map<Character ,Integer> infos=new HashMap<>();//{}
        //3.遍历80个学生选择的数据
        for (int i = 0; i < sb.length(); i++) {
            //提取当前选择
            char ch=sb.charAt(i);
            //判断Map集合中是否存在这个键
            if(infos.containsKey(ch)){
                infos.put(ch,infos.get(ch)+1);
            }else{
                //说明此经典是第一次统计
                infos.put(ch,1);
            }
        }
        //输出集合
        System.out.println(infos);
    }
}

 

 

  

 

 

举报

相关推荐

学习java第14天

Java学习-第21天

学习java第8天

java学习第7天

学习java第12天

学习Java第16天

0 条评论