Java 8 中引入了新特性,流式编程思想,为其增加了有一个新的亮点!因为流的一个核心好处是,使得代码程序更加精简并且更易理解。在某些数情况下,将对象存储在数组、集合中是为了处理他们,而现在你可以把编程的主要焦点从其转移到了流上,使得java更具有吸引力。下面看一些实例:
1、随机展示 1 至 50 之间不重复的整数并进行排序。实际上,你的关注点首先是创建一个有序集合。使用流式编程,你就可以简单的这样做:
public static void main(String[] args) {
new Random(47)
.ints(1, 50)
.distinct()
.limit(7)
.sorted()
.forEach(System.out::println);
}
有Java基础的伙伴们看到后可能会心一笑!这么简洁啊。
首先,我们给 Random 对象一个种子 ints()
方法产生一个流并且 ints()
方法产生一个整数流。 distinct()
来获取它们的非重复值,然后使用 limit()
方法获取前 7 个元素。sorted()
方法排序。最终使用 forEach()
方法遍历输出,它根据传递给它的函数对每个流对象执行操作。我们传递了一个可以在控制台显示每个元素的方法引用。System.out::println
相当于System.out.println
(),这是Java函数式编程思想的一种体现,以后会详细解读Java函数式编程。
2、每个集合可以通过调用 stream()
方法来产生一个流
public static void main(String[] args) {
Set w = new HashSet<>(Arrays.asList("You are a good student!".split(" ")));
w.stream().map(x -> x + " ").forEach(System.out::print);
System.out.println("...........");
Map m = new HashMap<>();
m.put("a", 9.9);
m.put("b", 26.8);
m.put("c", 1.0);
m.entrySet().stream().map(e -> e.getKey() + ": " + e.getValue()).forEach(System.out::println);
}
输出结果:
a are student! good You ...........
a: 9.9
b: 26.8
c: 1.0
所有集合 如 上w、 m 都有的 stream()方法,然后
map()
会获取流中的所有元素,并且对流中元素进行操作从而产生新的元素,并将其传递到流中。通过map()
会获取对象并产生新的对象,但是这里有特殊版本的方法用于数值类型的流。例如,mapToInt()
方法将一个对象流(objects stream)转换成为包含整形数字的 IntStream
。同样,针对 String 和 Double
也有类似名字的操作。
为了从 Map 集合中产生流数据,我们首先调用 entrySet()
去产生一个对象流,每个对象都包含一个 key
键以及与其相关联的 value
值。然后调用 getKey()
和 getValue()
将其分开遍历。
3、使用 Collectors 类来收集元素到特定的结果集合中 如:tocollect() 、.toCollection()、.toMap()等
public static void main(String[] args) {
List fileToWords = new ArrayList<>();
fileToWords.add("nandao");
fileToWords.add("nandao");
fileToWords.add("ytao");
fileToWords.add("mage");
ArrayList words =
fileToWords.stream()
.collect(ArrayList::new,
ArrayList::add,
ArrayList::addAll);
words.stream()
.filter(s -> s.equals("nandao")).collect(Collectors.toList())
.forEach(System.out::println);
}
输出结果:
nandao
nandao
这里有两个重要的语法:
A、collect(Collector)
:使用 Collector 来累计流元素到结果集合中,如:collect(Collectors.toList()) 源码如下:
B、collect(Supplier, BiConsumer, BiConsumer)
:同上,但是 Supplier 创建了一个新的结果集合,第一个 BiConsumer是将下一个元素包含在结果中的函数,而第二个 BiConsumer 是用于将两个值组合起来,源码如下:
public static
Collector> toList() {
return new CollectorImpl<>((Supplier>) ArrayList::new, List::add,
(left, right) -> { left.addAll(right); return left; },
CH_ID);
}
4、从一个list对象里取出对象的某一个参数,返回list:
List userList = param.getUserList();
List userIdList = userList.stream().map(UserInfo::getId).collect(Collectors.toList());
5、list中对象取出一个参数作为key,对象作为value 或者其他的一个属性作为value。
List userList = param.getUserList();
Map userIdMap = userList.stream().collect(Collectors.toMap(UserInfo::getId, t -> t));
Map userIdMap = userList.stream().collect(Collectors.toMap(UserInfo::getId, UserInfo::getName));
注意:要求list对象里有不能重复的key,否则转化时报错!
6、 list中生成map分组,相同key的对象放在一个集合里
List userList = param.getUserList();
Map> userNoMap = userList.stream().collect(Collectors.groupingBy(UserInfo::getNo));
大家可以细看一下 ,两个方法的核心是一样的。从今以后平时写代码的时候就可以替换for 、forEach循环了,让自己的代码更加简洁、高效、易于理解。(这就是流式编程比声明式编程好的地方!)
7、循环操作:
deleteList.forEach(entity -> {entity.setOil(compareBigDecimal);});
理论参考
理论参考2
使用参考
使用参考2
使用参考3
今天先讲到这里,小伙伴有哪里不明白的地方,可以随时留言!