一、Stream流

是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。

“集合讲的是数据,流讲的是计算!”

Stream 自己不会存储元素,Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

一般开发的套路是:创建一个Stream:一个数据源(数组、集合)-->中间操作:一个中间操作,处理数据源数据-->终止操作:一个终止操作,执行中间操作链,产生结果。

1、JDK1.8中的函数式接口与流

在jdk1.8中有一个包 java.util.function,存放的都是函数式接口这些函数式接口,大致分为下图几中类型类:

1、函数型接口,一个参数,一个返回值

//R apply(T t);Function<String,Integer> function = t ->{return t.length();};System.out.println(function.apply("abcd"));

2、断定型接口,一个参数,返回boolean

//boolean test(T t);Predicate<String> predicate = t->{return t.startsWith("a");};System.out.println(predicate.test("a"));

3、消费型接口,一个参数,没有返回值

// void accept(T t);Consumer<String> consumer = t->{System.out.println(t);};consumer.accept("javaXXXX");

4、供给型接口,无参数,有返回值

//T get(); Supplier<String> supplier =()->{return UUID.randomUUID().toString();};System.out.println(supplier.get());
package day12;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;/*** 请按照给出数据,找出*  * 偶数ID*  * 年龄大于24*  * 用户名转为大写*  * 用户名字母倒排序*  * 只输出2个*  //首先我们需要一个数据源  集合或者数组*         List<User> list =new ArrayList<User>();*         list.add(new User(11,"zhangsan",25));*         list.add(new User(12,"lisi",25));*         list.add(new User(13,"wangwu",35));*         list.add(new User(14,"zhaoliu",15));*         list.add(new User(15,"tanxin",38));*         list.add(new User(16,"wang",45));*/
public class TestStream {public static void main(String[] args) {List<User> list =new ArrayList<User>();list.add(new User(11,"zhangsan",25));list.add(new User(12,"lisi",25));list.add(new User(13,"wangwu",35));list.add(new User(14,"zhaoliu",15));list.add(new User(15,"tanxin",38));list.add(new User(16,"wang",45));/***   使用stream流*/Stream<User> stream = list.stream();/*** 可以通过工具类获取数组的Stream流*String[] arr = {"张三"};* Stream<String> stream1 = Arrays.stream(arr);*//***  过滤 filter*   返回true 表示保留,返回false 代表过滤*  map*    将集合中的元素一个个传递进来,然后经过处理再返回回去*  limit*    限定输出的个数*  foreach*    对集合中的元素循环遍历。*    sorted*       排序,里面可以放入一个比较器*   collect*      从一个集合中获取一个Stream流,通过流进行数据的处理,处理完之后,我们实际的集 *      合里面的元素是不会发生改变的。*      我们如果想将处理完的流Stream对象变为list 集合,需要使用到 collect*      收集的意思:  可以收集成list ,  set*      该方法是流对象的方法,不能在forEach 方法后调用。*/List<User> userList = stream.filter(user -> {if (user.getId() % 2 == 0) {return true;}return false;}).filter(user -> {if (user.getAge() > 24) {return true;}return false;}).map(user -> {String daXie = user.getName().toUpperCase();StringBuffer stringBuffer = new StringBuffer(daXie);System.out.println(stringBuffer.toString());user.setName(stringBuffer.reverse().toString());return user;}).sorted((u1, u2) ->//u1.getAge() - u2.getAge()u1.getName().compareTo(u2.getName())).limit(2).collect(Collectors.toList());/*forEach(user->{System.out.println(user);})*/System.out.println(userList);}
}

二、案例(Stream流)

问题:

/**
* 请按照给出数据,找出
* 偶数ID
* 年龄大于24
* 用户名转为大写
* 用户名字母倒排序
* 只输出一个
* 用户名字
*/

举例:

package day12;public class User {private int id;private String name;private int age;public User(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "User{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}
}
package day12;import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;/** 请按照给出数据,找出* 偶数ID* 年龄大于24* 用户名转为大写* 用户名字母倒排序* 只输出2个**   Stream   流  很重要,因为现在很多地方都这么写了,一定要重视一下*     常用的方法:*        filter  接收的是断定型接口*        map     接收的是函数型接口*        sorted   接收一个比较器*        forEach  接收一个消费性接口*        limit  表示显示多少行**/
public class TestStreamMain {public static void main(String[] args) {//首先我们需要一个数据源  集合或者数组List<User> list =new ArrayList<User>();list.add(new User(11,"zhangsan",25));list.add(new User(12,"lisi",25));list.add(new User(13,"wangwu",35));list.add(new User(14,"zhaoliu",15));list.add(new User(15,"tanxin",38));list.add(new User(16,"wang",45));Stream<User> stream = list.stream();// filter 过滤   里面需要接收一个断定型接口// 因为是对list集合进行遍历,所以p指的就是一个个的userstream.filter( p-> {if(p.getId()%2==0){return true;}return false;// filter 可以用来过滤数据}).filter( p->{if(p.getAge()>24){return true;}return false;// map 可以用来修改数据}).map( p->{p.setName(p.getName().toUpperCase());return p;// sorted 对数据按照一定规则排序,里面使用到了比较器这样一个接口}).sorted((user1, user2) -> {return user2.getName().compareTo(user1.getName());}).limit(1).forEach(System.out::println); //等同于如下操作/*forEach((t)->{System.out.println(t);})*/;}
}

二、Map集合

1、Map集合的常用方法

 map集合的常用方法/***   Map 是一个接口,父接口不是Collection*   Map 接口他的有名的实现类 HashMap*   他跟之前的集合相比,最大的不同就是 是以键值对形式出现的。*   Map 集合又称之为本地缓存(jvm内存中的)。*/Map<String, String> map = new HashMap<>();1、put 存放数据, 而且有返回值,如果key已经存在,就覆盖掉原来的value,并且返回被覆盖掉的 值,如果不是覆盖,返回nullmap.put("100","小二");map.put("200","小四");map.put("300","小三");       2、get 通过key 值获取 valueSystem.out.println(map.get("100"));如果出现相同的key值,会覆盖原来的数据String name = map.put("100", "王德法");System.out.println(name);null可以当做map集合中的key 和 valuemap.put(null,"路遥");map.put("400",null);System.out.println(map);System.out.println(map.get(null));put是覆盖,putIfAbsent是存在就插入不了了,不是覆盖,而且返回已经存在的值String name2 = map.putIfAbsent("300", "无名"); //打印出来的是小三 System.out.println(name2);HashMap<String, String> m = new HashMap<>();m.put("176","郑局");m.put("184","王总");m.put("188","张局");map.putAll(m);System.out.println(map);3、remove  删除键值对map.remove("176");           //通过Key  删除键值对map.remove("188","张局");  // 通过key 和 value 删除键值对System.out.println(map);4、map.clear();    清空集合。5、replace(key, oldValue, newValue)  //只有当key和oldValue是匹配的//情况下,才会将值修改成newValue。boolean b = map.replace("184","王总","赵厅");  //返回值为booleanSystem.out.println(map);6、replaceAll(BiFunction<K,V,V> biFunction) //对集合中的元素进⾏批量的替换将集合中的每⼀个键值对,带⼊到BiFunction的⽅法中, 使⽤接⼝⽅法的返回值替换集合中原来的值。map.replaceAll(new BiFunction<String, String, String>() {@Overridepublic String apply(String key, String value) {System.out.println("k="+key);System.out.println("v="+value);if(null != key && Integer.valueOf(key) > 300){return "hello" + value;}else{return "world";}}});7、get(K key)//通过键, 获取值。 如果键不存在, 返回null。  8、getOrDefault(K key)//通过键, 获取值。 如果键不存在, 返回默认的值。9、size()//获取集合中的元素数量(有多少个键值对)10、isEmpty()//判断集合是否为空11、containsKey(K key)//判断是否包含指定的键containsValue(V value)//判断是否包含指定的值12、keySet()// 获取由所有的键组成的集合(因为键是不允许重复的,因此这⾥返回的是Set集合)13、values()//获取由所有的值组成的集合

2、Map集合的三种遍历方式

HashMap<String, String> m = new HashMap<>();m.put("176","郑局");m.put("184","王总");m.put("188","张局");//第一种,获取里面所有的键值对,通过key 获取valueSet<String> keys = m.keySet();for (String key:keys) {System.out.println("Key="+key+",value ="+m.get(key));}//第二种, forEach获取m.forEach(new BiConsumer<String, String>() {@Overridepublic void accept(String key, String value) {System.out.println("Key="+key+",value ="+m.get(key));}});//Lambda表达式输出m.forEach((key,value) -> System.out.println("Key="+key+",value ="+m.get(key)));// 第三种:使用Entry 获取 key value值Set<Map.Entry<String, String>> entrySet = m.entrySet();for (Map.Entry<String,String> entry:entrySet) {System.out.println("Key="+entry.getKey()+",value ="+entry.getValue());}

3、Hashtable

HashMap与Hashtable两者对比:

1. HashMap是线程不安全的集合, Hashtable是线程安全的集合。
2. HashMap允许出现null键值, Hashtable是不允许的。
3. HashMap的父类是AbstractMap, Hashtable的父类是Dictionary。
4. HashMap的Map接口的新的实现类, 底层算法效率优于Hashtable。

4、TreeMap

原理实现:

与TreeSet⼀样,进⾏排列,只是TreeMap是按照键的⼤⼩实现,对于值是不管的。我们可以将TreeSet中的值理解成TreeMap中的键。

TreeMap 是有序的,指的是Key有序。

5、LinkedHashMap

HashMap  -->  LinkedHashMap
HashMap 中存储了多个元素,打印输出的时候,不按照当时存入的顺序打印。
LinkedHashMap 打印就是按照存储的顺序来的。

6、HashMap的存储原理

HashSet 底层数据结构是哈希表

JDK1.8之前结构:数组+链表

JDK8里面:数组+链表+红黑树

JDK1.8之后结构:节点数少于8个的时候采用数组+链表的结构,当节点数多于8个的时候,采用的是数组+红黑树的结构 。

HashMap存储的数据存放在内存中,提高HashMap数据寻址速度是重点要解决的问题,所以HashMap底层的存储结构非常关键,如果使用数组存储,时间复杂度为O(1),使用链表存储,时间复杂度为O(n),如果使用二叉树存储,时间复杂度为O(lg(n))。所以HashMap优先使用数组存储,如果出现hash碰撞,采用链表存储,如果链表长度大于8,寻址速度明显下降,进一步采用红黑树存储,将寻址效率提高。

当存放两个元素获取Hash并且Mod 16得到Hash桶编号相同时,出现Hash碰撞,hash桶使用链表存储这两个对象,使用HashMap.get(key)获取这两个对象时,需要两步实现,首先得到它们对应的Hash桶号,在根据Key与链表中的Key1=Value1比较key.equale(key1),找出对应元素,这样需要递归遍历列表中的元素,执行效率降低。当链表长度大于8时,HashMap将链表存储转化为红黑树存储,红黑树遍历每次可以减少一个分支,效率比链表高,其时间复杂度为O(lg(n))。

7、  HashMap 的扩容规则

HashMap使用数组存储,默认长度为16,加载因子为0.75,当HashMap的Hash桶数量的75%被分配使用时,HashMap扩容为原来的两倍。 跟HashSet一样。

【Day12-Stream流Map集合】相关推荐

  1. java8新特性-stream对map集合进行过滤的方法

    java8新特性-stream对map集合进行过滤的方法 stream对map集合进行过滤的方法

  2. Java8中Stream流对集合操作

    java8中Stream流引入函数式编程思想,主要配合各种接口.lambda表达式.方法引用等方式,为集合的遍历.过滤.映射等提供非常"优雅"的操作方式. Student.java ...

  3. java8 stream流操作集合交集,差集,并集,过滤,分组,去重,排序,聚合等

    测试对象 public class Person {private String name;private Integer age;private Integer weight;public Pers ...

  4. 使用stream流进行集合排序取最大值,根据集合中的bigdemal属性排序(正序反序)并取最大值

    业务: 求折线图的UPH图相关数据,前端动态修改纵轴的峰值,需要后端获取最大值 1)根据集合某个属性(业务以bigdecimal数据为例)进行集合排序,包括升序反序 2)根据集合的某个number数值 ...

  5. 使用Stream流对集合排序

    文章目录 0 写在前面 1 格式 1.1 介绍: 1.2 单个属性排序格式: 1.3 多个属性排序格式: 1.4 注意事项 2 代码举例 0 写在前面 有一些业务需要对集合按照一些规则进行排序,本篇介 ...

  6. Java8 stream流map方法使用

    直接上代码,顺便演示了从匿名内部类→lamdba表达式: /*** stream流的map方法的作用* 将当前流中的元素从一种类型转换为另一种类型存储到新流中* map 方法中隐含的函数式接口是 Fu ...

  7. 利用Java8新特性stream流给集合中的某个属性赋值

    今天在编写一个返回对象VO时,需要做一些处理,返回对象VO如下: CollectListVO @Data @JsonIgnoreProperties(ignoreUnknown = true) @Ap ...

  8. java8 stream流 .map

    java8 .map的使用 大家好,我是菜鸟!我胡汉三又来了 ...最近在看流 ,对.map 的使用一知半解的,甚是难过 ,特此一记!!! what is .map ? 用大白话讲就是从一个流到另一个 ...

  9. stream流map 多个字段_stream流根据对象指定字段去重

    先封装一个去重的方法 import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.fun ...

最新文章

  1. 凸函数和非凸函数---and why
  2. 【selenium 3】 Mac 下测试环境搭建 Firefox 47+ gecko driver Mac
  3. python 二分法实现pow_Python实现二分法和黄金分割法
  4. 怎么查看ftp服务器的版本信息,查看ftp服务器版本
  5. javascript里的post和get有什么区别
  6. Objective-C使用位运算设计可复选的枚举
  7. lua windows下编译
  8. 最佳调度问题(SSOJ-2367)
  9. Java多线程学习笔记-线程的使用
  10. 一加9 Pro真机图曝光:哈苏相机联名logo助力影像旗舰
  11. 欧洲与北美5G开战,最后的赢家却是高通?
  12. 爱奇艺回应遭做空;百度 App 部分频道停更;React Native 0.62 发布 | 极客头条
  13. 网络中各层协议(7层)
  14. 计算机组成原理(2021最新版)面试知识点集锦
  15. Codesys基础应用----ST语言实现经典冒泡排序
  16. 32. Make Sure public inheritance models is-a.
  17. 随机数生成器python_python安全开发军规之四:使用安全的随机数生成器
  18. 采集本地HTML数据,火车采集器保存为本地word、excel、html、txt文件方法及文件模板_爬虫软件技术与爬虫软件网页数据采集器门户...
  19. 黑客比程序员高在哪里?
  20. Winform多选树

热门文章

  1. 了解适用于Android应用程序的本机,WebView和混合模板
  2. ArcGIS快速加载在线地图
  3. 海盐、低钠岩盐、腌制盐……这么多盐到底有什么不同啊?
  4. 【腾讯Bugly干货分享】聊聊苹果的Bug - iOS 10 nano_free Crash
  5. “EA 交易”运行期间平衡曲线斜率的控制
  6. Git版本回退的两种方式_艾孜尔江撰
  7. Windows 文本大文件查看工具
  8. DATABASE SYSTEM CONCEPTS
  9. 解决tplink wn726 无线网卡在linux下不能使用的问题
  10. background-size设置背景图片自适应 在ie8下失效的问题