首页 > 其他分享 >day17

day17

时间:2023-03-18 15:58:09浏览次数:40  
标签:HashMap Stream 元素 day17 键值 集合 public

day17

可变参数

  • 就是说一种特殊形参,定义在方法、构造器的形参列表里,格式是:数据类型...参数名称

可变参数的1特点与好处

  • 特点:可以不传数据给它,可以传一个或者同时多个数据给它;也可以传一个数组给它

  • 好处:常常用来灵活的接受数据

可变参数的本质就是一个数组

可变参数的注意事项

  • 可变参数在方法内部就是一个数组
  • 可变参数必须放在形参列表的最后面
  • 一个形参列表的可变参数只能有一个

可变参数的应用场景

  • 可以很方便的创建集合对象

Collections是一个集合工具类,方便操作集合

方法名称 说明
public static boolean addAll(Collection<? super T> c, T... elements) 给集合批量添加元素
public static void shuffle(List<?> list) 打乱List集合中的元素顺序
public static void sort(List list) 对List集合中的元素进行升序排序
public static void sort(List list,Comparator<? super T> c) 对List集合中元素,按照比较器对象指定的规则进行排序

Map集合

  • Map集合称为双列集合,格式:{key1 = value1,key2 = value2,...}一次需要存一对数据作为一个元素
  • Map集合的每个元素“Key=value”称为一个键值对/键值对对象/一个Entry对象,Map集合也被叫做键值对集合
  • Map集合的所有键是不允许重复的,但是值可以重复,键和值是一一对应的,每一个键只能找到自己对应的值

调用put方法时,如果添加重复的Key,会覆盖Key的value值

Map集合体系的特点

注意:Map系列集合的特点都是由键决定的,值只是一个附属品,值是不作要求的

  • HashMap(由键决定特点):无序、不重复、无索引;(用的最多)
  • LinkedHashMap(由键决定特点):有序、不重复、无索引
  • TreeMap(由键决定特点):无序、不重复、无索引

Map集合常用方法

  • Map集合是双列集合的祖宗,他的功能是全部双列集合都可以继承过来使用的
方法名称 说明
public V put(K key,V value) 添加元素
public int size() 获取集合的大小
public void clear() 清空集合
public boolean isEmpty() 判断集合是否为空,为空返回true , 反之
public V get(Object key) 根据键获取对应值
public V remove(Object key) 根据键删除整个元素
public boolean containsKey(Object key) 判断是否包含某个键
public boolean containsValue(Object value) 判断是否包含某个值
public Set keySet() 获取全部键的集合
public Collection values() 获取Map集合的全部值

遍历Map集合的三种方式

  1. 获取所有Key的集合然后遍历,通过Key值获取对应的value值

    方法名称 说明
    public Set keySet() 获取所有键的集合
    public V get(Object key) 根据键获取其对应的值
  2. 把键值对看成一个整体进行遍历(难度较大)

    Map提供的方法 说明
    Set<Map.Entry<K, V>> entrySet() 获取所有“键值对”的集合
    Map.Entry提供的方法 说明
    K getKey() 获取键
    V getValue() 获取值
  3. Lambda表达式

方法名称 说明
default void forEach(BiConsumer<? super K, ? super V> action) 结合lambda遍历Map集合
public class forDemo {
    public static void main(String[] args) {
        HashMap<String, Integer> maps = new HashMap<>();
        String[] arr = {"A","B","C","D"};

        for (int i = 0;i < 80;i++){
            Random random = new Random();
            String s = arr[random.nextInt(arr.length)];
            int v = maps.getOrDefault(s,0);//HashMap 的 getOrDefault(Object key, V defaultValue) 方法用于获取指定键对应的值,如果键不存在,则返回默认值。
            maps.put(s,v+1);
        }
//循环遍历 keySet
        Set<String> keySet = maps.keySet();
        for (String key : keySet) {
            Integer value = maps.get(key);
            System.out.println(key +"--"+value);
        }
        System.out.println("----------------------------");
        //entrySet
        Set<Map.Entry<String,Integer>> entries = maps.entrySet();
        for (Map.Entry<String, Integer> entry : entries) {
            System.out.println(entry.getKey()+"---"+entry.getValue());
        }
        System.out.println("----------------------------");
//forEach
        maps.forEach(new BiConsumer<String, Integer>() {
            @Override
            public void accept(String s, Integer integer) {
                System.out.println(s+"----"+integer);
            }
        });
       //forEach+lambda 
        maps.forEach((key,value)-> System.out.println(key +"-"+value));
    }
}

HashMap

底层原理

哈希表

HashMap的底层实现是一个数组和链表(或红黑树)的结合体,它通过哈希函数将键映射到数组中的一个位置上,并将对应的值存储在这个位置上。

HashMap的底层原理如下:

  1. 初始化:HashMap创建时会创建一个默认大小的数组,这个数组大小是16,同时会计算出一个装载因子0.75,表示当数组中的元素数量达到总容量的75%时,就需要扩容。

  2. 插入:当用户调用put()方法插入键值对时,首先会根据键的哈希值计算出它在数组中的索引位置。如果这个位置还没有元素,则将这个键值对直接存储在这个位置上;如果这个位置已经存在元素,就需要遍历这个位置上的链表(或红黑树),找到对应的键值对,并更新它的值。

  3. 扩容:当HashMap中元素的数量达到总容量的75%时,就会自动进行扩容。具体来说,它会创建一个新的数组,大小是原来的两倍,并将所有元素重新插入到新的数组中。

  4. 查询:当用户调用get()方法查询某个键对应的值时,HashMap会根据键的哈希值计算出它在数组中的索引位置,并在该位置上的链表(或红黑树)中查找对应的键值对。

  5. 删除:当用户调用remove()方法删除某个键值对时,HashMap会根据键的哈希值计算出它在数组中的索引位置,并在该位置上的链表(或红黑树)中查找对应的键值对,并将它从链表(或红黑树)中删除。

    HashMap特点

HashMap集合是一种增删改查数据,性能都比较好的集合

他是无序,不能重复,没有索引支持的(由键决定特点)

HashMap的键依赖HashCode方法和equals方法保证键的唯一

如果键存储的是自定义类型的对象,可以通过重写HashCode和equals,这样可以保证多个对象内容一样时,HashMap集合就能认去重了

LinkedHashMap

  • 有序 不重复 无索引

底层原理

LinkedHashMap是HashMap的一个子类,它的底层实现方式基本上和HashMap相同,只不过在HashMap的基础上增加了一个双向链表来维护插入顺序或访问顺序,因此它既可以保持键值对的插入顺序,也可以按照访问顺序进行遍历。

TreeMap

  • 无序、不可重复、无索引、但可按照指定规则排序

TreeMap是Java集合框架中的一种实现,它是一种基于红黑树的有序映射表。在TreeMap中,每个键值对都存储在一个节点中,节点按照键的大小顺序排列组成一颗红黑树,这样就可以快速地查找、插入和删除节点。

TreeMap底层原理

下面是TreeMap底层的具体实现原理:

  1. 数据结构:TreeMap底层使用红黑树作为存储数据的数据结构。红黑树是一种自平衡的二叉查找树,它可以保证在最坏情况下,查找、插入和删除操作的时间复杂度都为O(logn)。
  2. 排序:TreeMap中的节点按照键的大小顺序排列。如果两个键的比较结果相同,那么它们被视为相等,只能存储一个键值对。TreeMap提供了两种比较方式:使用键的自然顺序(Natural Ordering)或者使用一个Comparator进行比较。
  3. 插入:在TreeMap中插入节点时,会根据键的大小顺序找到要插入的位置。如果要插入的键已经存在,那么它的值会被更新。插入节点后,需要保持红黑树的平衡性质。
  4. 删除:在TreeMap中删除节点时,会根据键的大小顺序找到要删除的节点。如果要删除的节点有两个子节点,那么需要找到它的后继节点(即大于该节点的最小节点)来替换它。删除节点后,需要保持红黑树的平衡性质。
  5. 遍历:TreeMap支持三种遍历方式:按键的自然顺序升序遍历、按键的自然顺序降序遍历、按照指定的Comparator进行遍历。这些遍历方式都是基于红黑树的中序遍历实现的。

Stream

简化集合、数组操作的API.结合了Lambda表达式

  • 也叫Stream流,JDK8开始新增的一套API,可以用于操作集合或者数组的数据。

  • 优势:Stream流大量结合了Lambda的语法风格来编程,提供了一种更加强大,更加简单的方式操作集合或者数组中的数据,代码更简洁,可读性更好

Stream 的操作可以分为两类:中间操作和终止操作。中间操作可以返回一个新的 Stream 对象,终止操作则可以将 Stream 转换为另外一种数据类型(如 List、Set、Map、数组等),或对集合进行统计、归约等操作。

Stream操作步骤

2.获取Stream流

获取集合的Stream流

Collection提供的如下方法 说明
default Stream stream() 获取当前集合对象的Stream流

获取数组的Stream流

Arrays类提供的如下 方法 说明
public static Stream stream(T[] array) 获取当前数组的Stream流
Stream类提供的如下 方法 说明
public static Stream of(T... values) 获取当前接收数据的Stream流

2.Stream流的中间方法

  • 中间方法指的是调用完成后会返回新的Stream流,可以继续使用(支持链式编程)。
  1. filter(Predicate<T> predicate):过滤出符合条件的元素。

  2. map(Function<T, R> mapper):将元素进行映射,返回一个新的 Stream。

  3. flatMap(Function<T, Stream<R>> mapper):将元素进行映射,并将所有 Stream 中的元素合并为一个 Stream。

  4. sorted(Comparator<T> comparator):对元素进行排序。

  5. distinct():去除重复的元素。

  6. limit(long maxSize):截取前 maxSize 个元素。

  7. skip(long n):跳过前 n 个元素。

  8. reduce(T identity, BinaryOperator<T> accumulator):将元素聚合为一个值。

  9. collect(Collector<T, A, R> collector):将元素收集到一个容器中。

  10. forEach(Consumer<T> action):对每个元素执行操作。

  11. Stream提供的常用中间方法 说明
    Stream filter(Predicate<? super T> predicate) 用于对流中的数据进行过滤。
    Stream sorted() 对元素进行升序排序
    Stream sorted(Comparator<? super T> comparator) 按照指定规则排序
    Stream limit(long maxSize) 获取前几个元素
    Stream skip(long n) 跳过前几个元素
    Stream distinct() 去除流中重复的元素。
    Stream map(Function<? super T,? extends R> mapper) 对元素进行加工,并返回对应的新流
    static Stream concat(Stream a, Stream b) 合并a和b两个流为一个流

3.Stream流常见的终结方法

  • 收集Stream流:就是把Stream流操作后的结果转回到集合或者数组中去返回
  • Stream流:方便操作集合/数组的手段;
  • 集合/数组:才是开发中的目的
Stream提供的常用终结方法 说明
void forEach(Consumer action) 对此流运算后的元素执行遍历
long count() 统计此流运算后的元素个数
Optional max(Comparator<? super T> comparator) 获取此流运算后的最大值元素
Optional min(Comparator<? super T> comparator) 获取此流运算后的最小值元素

Stream的注意事项

  1. Stream流中无法直接修改集合,数组等数据源中的数据
  2. 同一个Stream对象只能调用一次方法

标签:HashMap,Stream,元素,day17,键值,集合,public
From: https://www.cnblogs.com/xkh-blogs/p/17230951.html

相关文章