1、Stream.map
其作用接收一个泛型T,返回泛型R,map函数的定义,返回的流,表示的泛型是R对象,这个表示,调用这个函数后,可以改变返回的类型。
map方法的源码如下:
/**
*这个接口,接收一个泛型T,返回泛型R,map函数的定义,返回的流,表示的泛型是R对象,这个表示,调用这个函数后,可以改变返回的类型
*/
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
使用实例(将一个Integer类型的转换为一个Stringl类型):
public class ConvertType {
public static void main(String[] args) {
Integer[] nums = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Stream.of(nums).map(intValue -> String.valueOf(intValue)).forEach( vo -> {
System.out.println(vo);
System.out.println(vo.getClass()); // class java.lang.String
});
}
}
从main方法执行的结果可以发现经过map的处理Stream中的对象已经从Integer --> String
要将其返回值类型也修改可以如下操作:
public static void main(String[] args) {
Integer[] nums = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
List<String> list = Stream.of(nums).map(intValue -> String.valueOf(intValue)).collect(Collectors.toList());
}
2、Stream.collect()方法
一转为字符串:
直接使用Stream对象的collect方法传入Collectors.joining()),其中joining方法是一个重载方法。
使用一、直接joining()不传任何参数如下:
public static void main(String[] args) {
Integer[] nums = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
String str = Stream.of(nums).map(intValue -> String.valueOf(intValue)).collect(Collectors.joining());
System.out.println(str); // "12345678910"
System.out.println(str.getClass()); // class java.lang.String
}
使用二、传入一个类型为CharSequence的 delimiter参数,其作用是,根据输入的delimiter参数按遇到的顺序由delimiter作为分隔符分隔
其源码如下:
public static Collector<CharSequence, ?, String> joining(CharSequence delimiter) {
return joining(delimiter, "", "");
}
具体使用如:
public static void main(String[] args) {
Integer[] nums = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
String str = Stream.of(nums).map(intValue -> String.valueOf(intValue)).collect(Collectors.joining("-"));
System.out.println(str); // "1-2-3-4-5-6-7-8-9-10"
System.out.println(str.getClass()); // class java.lang.String
}
使用三:joining(CharSequence delimiter,CharSequence prefix, CharSequence suffix),根据传入的delimiter顺序的分隔符进行分隔,根据传入的prefix作为前缀拼接串,根据suffix作为后缀串进行拼接。
源码如下:
public static Collector<CharSequence, ?, String> joining(CharSequence delimiter,
CharSequence prefix,
CharSequence suffix) {
return new CollectorImpl<>(
() -> new StringJoiner(delimiter, prefix, suffix),
StringJoiner::add, StringJoiner::merge,
StringJoiner::toString, CH_NOID);
}
具体使用如:
public static void main(String[] args) {
Integer[] nums = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
String str = Stream.of(nums).map(intValue -> String.valueOf(intValue)).collect(Collectors.joining("-",
"prefix", "suffix"));
System.out.println(str); // "prefix1-2-3-4-5-6-7-8-9-10suffix"
System.out.println(str.getClass()); // class java.lang.String
}
二:转为LIst
直接使用Stream对象的collect方法传入Collectors.toList())
public static void main(String[] args) {
Integer[] nums = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
List<String> list = Stream.of(nums).map(intValue -> String.valueOf(intValue)).collect(Collectors.toList());
list.forEach(str -> System.out.println(str));
}
三:转为Set
直接使用Stream对象的collect方法传入Collectors.toSet())
public static void main(String[] args) {
Integer[] nums = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Set<String> set = Stream.of(nums).map(intValue -> String.valueOf(intValue)).collect(Collectors.toSet());
set.forEach(str -> System.out.println(str));
}
*四:转为Map
*
直接使用Stream对象的collect方法传入Collectors.toSet())
简单的对象转map:.
public static void main(String[] args) {
Integer[] nums = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Map<String, String> map = Stream.of(nums).map(intValue -> String.valueOf(intValue)).collect(Collectors.
toMap(String::toString, String::toString));
Iterator<String> iterator = map.values().iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
如何考虑到可能存在hash冲突问题可以引入mergefunction作为参数
mergefunction方法源码如下:
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction)
其作用是一个合并函数,它指出在发生冲突的情况下,我们保留现有条目,
具体使用如下:
public static void main(String[] args) {
Integer[] nums = new Integer[]{1,1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Map<String, String> map = Stream.of(nums).map(intValue -> String.valueOf(intValue)).collect(Collectors.
toMap(String::toString, Function.identity(), (existing, replacement) -> existing));
Iterator<String> iterator = map.values().iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
复杂对象转map.
首先先准备一个java对象如下:
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
}
具体使用如(使用具体的成员变量为key 和value):
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("user1", 18));
students.add(new Student("user2", 26));
students.add(new Student("user3", 30));
students.add(new Student("user4", 10));
Map<String, Integer> map = students.stream().collect(Collectors.toMap(Student::getName, Student::getAge));
}
或者使用对象作为value:
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("user1", 18));
students.add(new Student("user2", 26));
students.add(new Student("user3", 30));
students.add(new Student("user4", 10));
Map<String, Student> map = students.stream().collect(Collectors.toMap(Student::getName, Function.identity()));
map.values().forEach(vo -> System.out.println(vo));
}
或使用lambda表示设置key 和value:
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("user1", 18));
students.add(new Student("user2", 26));
students.add(new Student("user3", 30));
students.add(new Student("user4", 10));
Map<String, Student> map = students.stream().collect(Collectors
// 第一个参数为key.
// 第二为value;
// 第三个表示前后的key是相同,到是覆盖还是不覆盖,(s1,s2)-> s1表示不覆盖,(s1,s2)-> s2 表示覆盖。
.toMap(s -> s.getName(), s -> s, (s1, s2) -> s1));
map.values().forEach(vo -> System.out.println(vo));
System.out.println(map instanceof TreeMap); // true
}
默认情况下,tomap()方法将返回哈希映射。我们可以使用这个重载的toMap()方法,toMap方法可以将一个Stream对象转换成一个Map对象。源码如下:
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction,
Supplier<M> mapSupplier)
其中mapsupplier是返回带有结果的新空映射的函数。
返回一个ConcurrentHashMap,
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("user1", 18));
students.add(new Student("user2", 26));
students.add(new Student("user3", 30));
students.add(new Student("user4", 10));
Map<String, Student> map = students.stream().collect(Collectors.toMap(Student::getName, Function.identity(),
(o1,o2) -> o1, ConcurrentHashMap::new
));
map.values().forEach(vo -> System.out.println(vo));
System.out.println(map instanceof ConcurrentHashMap); // true
}
返回一个TreeMap
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("user1", 18));
students.add(new Student("user2", 26));
students.add(new Student("user3", 30));
students.add(new Student("user4", 10));
Map<String, Student> map = students.stream().collect(Collectors.toMap(Student::getName, Function.identity(),
(o1,o2) -> o1, TreeMap::new
));
map.values().forEach(vo -> System.out.println(vo));
System.out.println(map instanceof TreeMap); // true
}
Collectors类的tomap()方法。它允许我们从流中创建一个新的映射
五 groupingBy方法
groupingBy是能够根据字段进行分组。
具体使用实例:
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("user1", 18));
students.add(new Student("user2", 26));
students.add(new Student("user3", 30));
students.add(new Student("user4", 10));
// 根据学生姓名进行分组
Map<String, List<Student>> map = students.stream().collect(Collectors.groupingBy(Student::getName));
map.values().forEach(vo -> System.out.println(vo));
}
或统计重名:
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("user1", 18));
students.add(new Student("user2", 26));
students.add(new Student("user3", 30));
students.add(new Student("user4", 10));
students.add(new Student("user4", 10));
// 统计年纪相同的学生
Map<String, Set<String>> collect = students.stream().collect(Collectors.
groupingBy(Student::getName, Collectors.mapping(Student::getName, Collectors.toSet())));
collect.values().forEach(vo -> System.out.println(vo));
}