13天Java进阶笔记-day6-Map

第一章 Map

Map集合的概述

Map集合是另一个集合体系。

Collection是单值集合体系。

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

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

Map集合也被称为“键值对集合”。

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

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

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

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):判断该集合中是否有此键。
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集合的遍历

Map集合的遍历方式有3种:

  • 键找值的方式遍历:先获取Map集合全部的键,再根据遍历键找值
  • 键值对的方式遍历
  • JDK1.8之后支持Lambda表达式

首先是键找值遍历方式

  • 先获取Map集合的全部键的Set集合
  • 遍历键的Set集合,然后通过键找值
Set<String> keys = maps.keySet();
for (String key : keys) {
    // 过键取对应的值
    Integer value = maps.get(key);
    System.out.println(key + "=" + value);
}

然后是键值对的方式遍历

  • Map集合转换成一个Set集合:Set<Map.Entry<K, V>> entrySet();
  • 此时键值对元素的类型就确定了,类型是键值对实体类型:Map.Entry<K, V>
  • 接下来就可以用foreach遍历这个Set集合,类型用Map.Entry<K, V>
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);
}

最后是简介的Lambda表达式

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

Map集合存储自定义类型

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

如果Map集合认为自定义类型的键对象重复了,必须重写对象的hashCode()equals()方法

Orange.java

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);
    }
    
    //...
}

Map使用自定义存储类型

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);

LinkedHashMap的特点

LinkedHashMapHashMap的子类,添加的元素按照键有序,不重复的。

HashSet集合相当于是HashMap集合的键都不带值。

LinkedHashSet集合相当于是LinkedHashMap集合的键都不带值。

底层原理完全一样,都是基于哈希表按照键存储数据的,

只是HashMap或者LinkedHashMap的键都多一个附属值。

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);
  • HashMap集合是无序不重复的键值对集合。
  • LinkedHashMap集合是有序不重复的键值对集合。
  • 他们都是基于哈希表存储数据,增删改查都很好。

TreeMap集合应用

  • TreeMap集合按照键是可排序不重复的键值对集合。(默认升序)
  • TreeMap集合按照键排序的特点与TreeSet是完全一样的

TreeMap集合和TreeSet集合都是排序不重复集合

TreeSet集合的底层是基于TreeMap,只是键没有附属值而已。

所以TreeMap集合指定大小规则有2种方式:

  • 直接为对象的类实现比较器规则接口Comparable,重写比较方法(拓展方式)
  • 直接为集合设置比较器Comparator对象,重写比较方法

类实现Comparable

// 比较者: 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);
}

集合设置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());
    }
});

第二章 排序算法

冒泡排序算法

int[] arr = new int[] {55, 22, 99, 88};
// 1.定义一个循环控制总共需要冒泡几轮:数组的长度-1
for(int i = 0 ;  i < arr.length - 1 ; i++ ){
    // i = 0   j = 0 1 2
    // i = 1   j = 0 1
    // i = 2   j = 0
    // 2.控制每轮比较几次。
    for(int j = 0 ; j < arr.length - i - 1 ; j++ ){
        // 如果当前元素大于后一个元素
        if(arr[j] > arr[j+1]){
            // 交换位置。大的元素必须后移!
            // 定义一个临时变量存储后一个元素
            int temp = arr[j+1];
            arr[j+1] = arr[j];
            arr[j] = temp;
        }
    }
}

选择排序算法

int[] arr = {5 , 1 , 3 , 2};
// 1.定义一个循环控制选择几轮
for(int i = 0 ; i < arr.length - 1 ; i++ ){
    // 2.定义一个循环控制每轮比较几次,一定是以当前位置与后面元素比较
    // i =0  j = 1 2 3
    // i =1  j = 2 3
    // i =2  j = 3
    // 遍历后面的元素
    for(int j = i+1 ; j < arr.length ; j++ ){
        // 拿当前位置与j指定的元素进行大小比较,后面的较小就交换位置
        if(arr[j] < arr[i]){
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }
}

第三章 二分查找

二分查找的前提:对数组是有要求的,数组必须已经排好序。

每次先与中间的元素进行比较,如果大于往右边找,如果小于往左边找,如果等于就返回该元素索引位置!

如果没有该元素,返回-1。综合性能比较好!!

/**
     *
     * @param arr  被检索的数组
     * @param number 被检索的元素值
     * @return  返回元素在数组中的索引值,不存在该元素返回-1
     */
public static int binarySerach(int[] arr , int number){
    // 3.记录当前区间搜索的开始索引和结束索引。
    int start = 0 ;
    int end = arr.length - 1;
    // 4.定义一个循环,反复去循环元素。
    while(start <= end){
        // 5.取中间索引位置
        int middleIndex = (start + end) / 2 ;
        // 6.判断当前元素与中间元素的大小
        if(number < arr[middleIndex]){
            // 7.往左边继续寻找,结束索引应该-1
            end = middleIndex - 1;
        }else if(number > arr[middleIndex]){
            start = middleIndex + 1;
        }else if(number == arr[middleIndex]){
            return middleIndex;
        }
    }
    // 如果上述循环执行完毕还没有返回索引,说明根本不存在该元素值,直接返回-1
    return -1;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值