目录
- Java之Lambda使用
- Stream接口中的常见方法
- 流操作
- 1.Java中filter和removeIf.
- 2.Java中forEach使用.
- 3.Java中Peek使用.
- 4.Java中Map使用.
- 5.Java中MapTo...使用.
- 6.Java中Distinct使用.
- 7.Java中Sorted使用.
- 8.Java中skip使用.
- 9.Java中flatMap使用.
- 10.Java中FindFirst、findAny 查找使用.
- 11.Java中Limit使用.
- 12.Java中Max,Min使用.
- 13.Java中 匹配 anyMatch allMatch noneMatch使用.
- 14.Java中归约 reduce使用.
- 15.Java中 数值范围 range rangeClosed使用.
- 16.Java中 值创建流使用.
- 17.Java中 数值流 mapToDouble、mapToLong、mapToInt使用.
- 18.Java中 收集器使用.
- 19.Java中Collectors.joining使用.
- 非流操作
Java之Lambda使用
Stream接口中的常见方法
List<Integer> nums =Arrays.asList(1,1,null,2,3,4,null,5,6,7,8,9,10);
System.out.println("sum is:"+nums.stream()
.filter(num -> num != null) // 流中:1,1,2,3,4,5,6,7,8,9,10
.distinct() // 流中:1,2,3,4,5,6,7,8,9,10
.mapToInt(num -> num * 2) // 流中:2,4,6,8,10,12,14,16,18,20
.peek(System.out::println) // 当元素被消费时,打印自身:2,4,6,8,10,12
.skip(2) // 流中:6,8,10,12,14,16,18,20
.limit(4) // 流中:6,8,10,12
.sum()); // 总计:36 = 6+8+10+12
结果:
2
4
6
8
10
12
sum is:36
流操作
1.Java中filter和removeIf.
- 介绍
- 区别:
- filter过滤, 会把符合的留下来.
- removeIf过滤之后, 会把相同的干掉.
- 区别:
- 示例
List<Student> stuList = new ArrayList<>();
Collections.addAll(stuList,
new Student(1, "张三"),
new Student(2, "李四"),
new Student(3, "王老五")
);
// 使用filter过滤之后(会把符合的留下来,比如:Student{stuId=1, stuName='张三'})
List<Student> filterList = stuList.stream().filter(student -> {
Integer valueOf = Integer.valueOf("1");
return !valueOf.equals(student.getStuId());
}).collect(Collectors.toList());
// 使用removeIf过滤之后(会把相同的干掉,比如干掉了“王老五”)
boolean removeIf = filterList.removeIf(student -> {
Integer valueOf = Integer.valueOf("3");
return valueOf.equals(student.getStuId());
});
// 最后剩下:Student{stuId=2, stuName='李四'}
filterList.forEach(System.out::println);
// 10. 使用filter保留两个集合的交集, stu02List_新的集合
stuList.stream().filter(stu02List::contains).collect(Collectors.toList());
// 11. 差集
List<User> resultList = createList().stream()
.filter(o->!newList.contains(o)).collect(Collectors.toList());
2.Java中forEach使用.
- 介绍
- 集合的遍历forEach方法
- 示例
// 1. 输出一列
list.stream().forEach(v -> System.err.println(v.getName()+","+v.getSex()));
// 2. 遍历Map集合
map.forEach((key, value) -> System.out.println("key:" + key + "; value" + JSON.toJSON(value)));
3.Java中Peek使用.
- 介绍
- peek 方法很简单,我们在 peek 方法里面做任意没有返回值的事情,比如打印日志.
- 与forEach()方法效果类似,但该方法会返回一个新的流,而forEach()无返回
- 示例
// 1. 打印日志
public void testPeek() {
List<String> list = new ArrayList<String>() {{
add("1");
add("2");
add("3");
}};
list.stream().map(s -> Integer.valueOf(s))
.peek(s -> System.out.println(s))
.collect(Collectors.toList());
}
// 2. 给List集合中某一个字段、数组赋值
wordVoList.stream().peek(aItem - > {
List<String> strList = xxxMapper.findAll();
aItem.setstuList(strList);
}
).collect(collectors.toList());
// 3. 使用peek调用方法给集合中字段赋值
.stream().peek(xxxServiceImpl::accept).collect(collectors.toList());
private static void accept(ExperienceVO aItem) {
if (不等于空) {
aItem.setCaseStatusFlag(ExperienceEnum.getValue(aItem.CaseStatus()));
}
}
4.Java中Map使用.
- 介绍
- map 方法可以让我们进行一些流的转化,比如原来流中的元素是 A,通过 map 操作,可以使返回的流中的元素是 B.
- 实例
// 1. 通过 map 方法list中元素转化成 小写
public void testMap() {
List<String> list = new ArrayList<String>() {{
add("1");
add("2");
add("3");
}};
List<String> strLowerList = list.stream()
.map(str -> str.toLowerCase())
.collect(Collectors.toList());
}
// 2. 将集合中某个字段转换为单独一个集合的两种方式.
List<Integer> listPlus = list.stream().map(value -> value.getId()).collect(Collectors.toList());
List<Integer> listPlus = list.stream().map(Student::getId).collect(Collectors.toList());
// 3. 将DTO转换为VO
private static List<LocationVo> convert2LocationVo(List<LocationDto> locationDtoList) {
if (null == locationDtoList) {
return null;
}
return locationDtoList.stream().map(item -> {
LocationVo locationVo = new LocationVo();
locationVo.setUpdateBy(item.getUpdateBy());
locationVo.setUpdateDate(item.getUpdateDate());
locationVo.setVersion(item.getVersion());
return locationVo;
}).collect(Collectors.toList());
}
// 4. Lambda .map this调用方法
//聚合方法
private List<StudentPlus> obj(List<Student> stuList) {
return stuList.stream().map(this::conversion).collect(Collectors.toList());
}
//转换方法
private StudentPlus conversion(Student stu) {
StudentPlus studentPlus = new StudentPlus();
studentPlus.setId(stu.getId());
studentPlus.setName(stu.getName());
studentPlus.setDate(new Date(stu.getDate()));
return studentPlus;
}
// 5.List<>转List<map<,>>
List<Map<String,Object>> personToMap = peopleList.stream().map((p) -> {
Map<String, Object> map = new HashMap<>();
map.put("is", p.getId());
map.put("age", p.getAge());
return map;
}).collect(Collectors.toList());
5.Java中MapTo...使用.
- 介绍
- mapToInt 方法的功能和 map 方法一样,只不过 mapToInt 返回的结果已经没有泛型,已经明确是 int 类型的流了,源码如下:
- 实例
public void testMapToInt () {
List<String> list = new ArrayList<String>() {{
add("1");
add("2");
add("3");
}};
List<Integer> collect = list.stream()
.mapToInt(s -> Integer.valueOf(s))
// 一定要有 mapToObj,因为 mapToInt 返回的是 IntStream,因为已经确定是 int 类型了
// 所有没有泛型的,而 Collectors.toList() 强制要求有泛型的流,所以需要使用 mapToObj
// 方法返回有泛型的流
.mapToObj(s -> s)
.collect(Collectors.toList());
double sum = list.stream()
.mapToDouble(s -> Double.valueOf(s))
// DoubleStream/IntStream 有许多 sum(求和)、min(求最小值)、max(求最大值)、average(求平均值)等方法
.sum();
}
6.Java中Distinct使用.
- 介绍
- distinct 方法有去重的功能
- 可在.map()、.stream()关键字之后使用.
- 实例
public void testDistinct(){
List<String> list = new ArrayList<String>() {{
add("1");
add("2");
add("2");
}};
list.stream()
.map(s -> Integer.valueOf(s))
.distinct()
.collect(Collectors.toList());
}
7.Java中Sorted使用.
- 介绍
- Sorted 方法提供了排序的功能,并且允许我们自定义排序
- 实例
public void testSorted() {
List<String> list = new ArrayList<String>() {{
add("1");
add("2");
add("3");
}};
list.stream()
.map(s -> Integer.valueOf(s))
// 等同于 .sorted(Comparator.naturalOrder()) 自然排序
.sorted()
.collect(Collectors.toList());
// 自定义排序器
list.stream()
.map(s -> Integer.valueOf(s))
// 反自然排序
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
}
// 2. 降序
.sorted(Comparator.comparing(ResourceFeverRankingVO::getDateSoft).reversed())
.collect(Collectors.toList());
// 3. 升序
studentList.stream().sorted(Comparator.comparing(StudentInfo::getAge)).collect(Collectors.toList())
8.Java中skip使用.
- 介绍
- 跳过流中前面几个元素, 下标从0开始
- 实例
List<String> list = new ArrayList<>();
Collections.addAll(list, "张三", "李四", "王老五", "潘丽平");
System.out.println(list.stream().skip(2).collect(Collectors.toList()));
// TODO 输出: [王老五, 潘丽平]
9.Java中flatMap使用.
- 介绍
- Lambda中Map是对流元素进行转换,flatMap 是对流中的元素(集合)进行平铺后合并,即对流中的每个元素平铺后又转换成为了 Stream 流。
- flatMap 首先将一个函数应用于元素,然后将其展平,当你需要将 [[a,b,c],[d,e,f],[x,y,z]] 具有两个级别的数据结构转换为 [a,b,c,d,e,f,x,y,z] 这样单层的数据结构时,就选择使用 flatMap 处理。
- 如果是 [a,b,c,d,e,f,x,y,z] 转换为大写 [A,B,C,D,E,F,X,Y,Z] 这样单层转换,就使用 map 即可。
- 示例
// 1.将一个字符串列表分割成单个字符列表:
// 输出 ["hello", "world"]转换为["h","e","l","l","o","w","o","r","l","d"]
List<String> dataList = Lists.newArrayList("hello", "world");
List<String> transform = dataList.stream()
.flatMap(
data -> Arrays.stream(data.split(""))
)
.collect(Collectors.toList());
System.out.println(JSON.toJSONString(transform));
// 2.将一个二维数组转换为一个一维数组:
int[][] array = {{1, 2}, {3, 4}, {5, 6}};
int[] flatArray = Arrays.stream(array)
.flatMapToInt(Arrays::stream)
.toArray();
System.out.println(Arrays.toString(flatArray)); // 输出 [1, 2, 3, 4, 5, 6]
// 3.将一个对象列表中的属性转换为一个列表
class Person {
private String name;
private List<String> hobbies;
// 省略构造函数和 getter/setter 方法
}
List<Person> personList = Arrays.asList(
new Person("Alice", Arrays.asList("reading", "swimming")),
new Person("Bob", Arrays.asList("hiking", "cooking"))
);
List<String> hobbyList = personList.stream()
.flatMap(person -> person.getHobbies().stream())
.collect(Collectors.toList());
System.out.println(hobbyList); // 输出 ["reading", "swimming", "hiking", "cooking"]
// 4. .map和.flatMap关键字配合使用
List<Person> people = Arrays.asList(
new Person("John", 30),
new Person("Jane", 25),
new Person("Bob", 40)
);
List<Integer> ages = people.stream()
.filter(person -> person.getAge() > 30)
.map(Person::getAge)
.flatMap(age -> Stream.of(age))
.collect(Collectors.toList());
// 输出 [40]
10.Java中FindFirst、findAny 查找使用.
- 介绍
- findAny查找前流中的任意元素
- findFirst查找第一个元素
- 实例
public class Menu {
/**
* 菜品名称
*/
private String name;
/**
* 菜品单价
*/
private Double price;
/**
* 菜品斤数
*/
private Double kilo;
/**
* 菜品类型:蔬菜、水果、肉类
*/
private String type;
}
Menu pork = new Menu("猪肉", 9.9, 10.0, "肉类");
Menu beef = new Menu("牛肉", 38.8, 5.0, "肉类");
Menu chicken = new Menu("鸡肉", 6.5, 30.0, "肉类");
Menu tomato = new Menu("土豆", 3.5, 30.0, "蔬菜");
Menu potato = new Menu("西红柿", 7.5, 20.0, "蔬菜");
Menu apple = new Menu("苹果", 3.5, 20.0, "水果");
Menu orange = new Menu("橙子", 4.0, 20.0, "水果");
List<Menu> menuList = Arrays.asList(pork, beef, chicken, tomato, potato, apple, orange);
// 苹果
menuList.stream().filter(menu -> menu.getType().equals("水果")).findFirst().ifPresent(menu -> System.out.println(menu.getName()));
// 苹果 (findAny查找前流中的任意元素)
Optional<Menu> fruitMenu = menuList.stream().filter(menu -> menu.getType().equals("水果")).findAny();
// 示例2 (findFirst查找第一个元素)
Optional<Menu> fruitMenu = menuList.stream().filter(menu -> menu.getType().equals("水果")).findFirst();
if (fruitMenu != null && fruitMenu.isPresent() && fruitMenu.get().getName() != null) {
System.out.println(fruitMenu.get().getName() +"--"+fruitMenu.get().getPrice());
}
// 输出 苹果--3.5
11.Java中Limit使用.
- 介绍
- limit 方法会限制输出值个数,入参是限制的个数大小
- 实例
public void testLimit(){
List<String> list = new ArrayList<String>() {{
add("1");
add("2");
add("3");
}};
list.stream()
.map(s -> Integer.valueOf(s))
.limit(2L)
.collect(Collectors.toList());
}
12.Java中Max,Min使用.
- 介绍
- 通过max、min方法,可以获取集合中最大、最小的对象
- 实例
public void testMaxMin(){
List<String> list = new ArrayList<String>() {{
add("1");
add("2");
add("2");
}};
list.stream().max(Comparator.comparing(s -> Integer.valueOf(s))).get();
list.stream().min(Comparator.comparing(s -> Integer.valueOf(s))).get();
}
13.Java中 匹配 anyMatch allMatch noneMatch使用.
-
介绍
-
示例
// 1.anyMatch检查谓词是否至少匹配一个元素
// 输出 true
boolean isVegetables = menuList.stream().anyMatch(menu -> menu.getType().equals("蔬菜"));
System.out.println(isVegetables);
// 2.allMatch检查谓词是否匹配所有元素
// 输出 false
boolean isAllVegetables = menuList.stream().allMatch(menu -> menu.getType().equals("蔬菜"));
System.out.println(isAllVegetables);
// 3.noneMatch确保流中没有任何元素与给定的谓词匹配
// 输出 true
boolean isNoneDrink = menuList.stream().noneMatch(menu -> menu.getType().equals("酒水"));
System.out.println(isNoneAllVegetables);
14.Java中归约 reduce使用.
- 介绍
- 归约:将流归约成一个值。
- 就像相加
- 示例
// 输出 73.69999999999999
double totalPrice = menuList.stream().map(Menu::getPrice).reduce(0.0, (a, b) -> a + b);
System.out.println(totalPrice);
// 保留一位小数 73.7
double totalPrice = menuList.stream().map(menu -> {return new BigDecimal(menu.getPrice());}).reduce(BigDecimal.ZERO, BigDecimal::add).doubleValue();
System.out.println(totalPrice);
// 归约查找最大值(找到最大值)
double maxPrice = menuList.stream().map(Menu::getPrice).reduce(Double::max).get();
System.out.println(maxPrice);
15.Java中 数值范围 range rangeClosed使用.
- 介绍
- 示例
// 1.rangeClosed 第一个参数接受起始值,第二个参数接受结束值。rangeClosed包含结束值。
IntStream is = IntStream.rangeClosed(1, 100).filter(i -> i % 2 == 0);
is.forEach(System.out::println);
// 输出 2 4 6 8 ...... 96 98 100
// 2.range 第一个参数接受起始值,第二个参数接受结束值。range是不包含结束值的
LongStream ls = LongStream.range(1, 100);
ls.forEach(System.out::println);
// 输出 1 2 3 4 ...... 97 98 99
16.Java中 值创建流使用.
- 介绍
- 示例
Stream<String> ss = Stream.of("ilob", "beh", "jb");
ss.map(String::toUpperCase).forEach(System.out::println);
// 输出 ILOB BEH JB
17.Java中 数值流 mapToDouble、mapToLong、mapToInt使用.
- 介绍
- 示例
// 1.mapToDouble
// 输出 73.69999999999999
double sum = menuList.stream().mapToDouble(Menu::getPrice).sum();
System.out.println(sum);
// 2.保留1位小数
// 输出 73.7
DecimalFormat df = new DecimalFormat();
df.setRoundingMode(RoundingMode.HALF_UP);
double sum = menuList.stream().mapToDouble(Menu::getPrice).sum();
System.out.println(df.format(sum));
// 3. mapToLong
// 输出 10
List<Long> longList = Arrays.asList(1L, 2L, 3L, 4L);
long longsum = longList.stream().mapToLong(Long::longValue).sum();
System.out.println(longsum);
// 4. mapToInt
// 输出 Sum of length: 21
List<String> list = Arrays.asList("apple", "banana", "orange", "kiwi");
int sum = list.stream().mapToInt(str -> str.length()).sum();
System.out.println("Sum of length: " + sum);
18.Java中 收集器使用.
- 介绍
- 示例
// 1.Collectors.counting() 统计流中元素的数量并返回计数结果
// 输出 7 7
long count = menuList.stream().count();
System.out.println(count);
System.out.println(menuList.stream().collect(Collectors.counting()));
// 2.Collectors.maxBy()
// 输出 38.8
double max = menuList.stream().collect(Collectors.maxBy(Comparator.comparing(Menu::getPrice))).get().getPrice();
System.out.println(max);
// 3.Collectors.minBy()
// 输出 3.5
double min = menuList.stream().collect(Collectors.minBy(Comparator.comparing(Menu::getPrice))).get().getPrice();
System.out.println(min);
// 4.Collectors.summingDouble() 计算流中元素的总和并返回总和结果
// 输出 135.0
double sum = menuList.stream().collect(Collectors.summingDouble(Menu::getKilo));
System.out.println(sum);
// 5.Collectors.averagingDouble() 计算流中元素的平均值并返回平均值结果
// 输出 19.29
DecimalFormat df = new DecimalFormat("#.00");
df.setRoundingMode(RoundingMode.HALF_UP);
double avg = menuList.stream().collect(Collectors.averagingDouble(Menu::getKilo));
System.out.println(df.format(avg));
// 6. Collectors.summarizingDouble() 计算流中元素的统计信息并返回一个DoubleSummaryStatistics对象,该对象包含了求和、平均值、计数、最大值和最小值等信息。
// 输出 DoubleSummaryStatistics{count=7, sum=73.700000, min=3.500000, average=10.528571, max=38.800000}
DoubleSummaryStatistics dss = menuList.stream().collect(Collectors.summarizingDouble(Menu::getPrice));
System.out.println(dss);
19.Java中Collectors.joining使用.
- 介绍
- 自定义连接字符串
- 实例
非流操作
1.Java中groupingBy使用.
- 介绍
- groupingBy 是能够根据字段进行分组
- toMap 是把 List 的数据格式转化成 Map 的格式
- groupingBy 是能够根据字段进行分组
- 实例
// 1. 自定义分组
public void testGroupBy(){
List<String> list = new ArrayList<String>() {{
add("1");
add("2");
add("2");
}};
Map<String, List<String>> strList = list.stream().collect(Collectors.groupingBy(s -> {
if("2".equals(s)) {
return "2";
}else {
return "1";
}
}));
}
// 2. 按类目进行分组
Map<String, List<Product>> prodMap= prodList.stream().collect(Collectors.groupingBy(Product::getCategory));
// 3. 先按照类别分组,再聚合求总数
prodList.stream()
.collect(Collectors.groupingBy(Product::getCategory, Collectors.counting()));
// 4. 先按照类别分组,再聚合运算(把num相加)
prodList.stream()
.collect(Collectors.groupingBy(Product::getCategory, Collectors.summingInt(Product::getNum)));
2.Java中Collect使用.
- 介绍
- 将操作后的对象转化为新的对象
- 实例
// 1.转换为List集合
list.stream().map(s -> Integer.valueOf(s)).collect(Collectors.toList());
// 2.可配合分组使用
// 3.转换为Map的2种方法
.collect(Collectors.toMap(String::valueOf, Function.identity()));
.collect(Collectors.toMap(PersonDto::getId, o -> o));
// 4.List转Map,id作为key,name作为value,id不可重复
Map<Long, String> collect = objects.stream().collect(Collectors.toMap(PersonDto::getId, PersonDto::getUserName));
// 5.List转Map,id作为key,name作为value,如果Id重复取第一个name
Map<Long, String> collect = objects.stream().collect(Collectors.toMap(PersonDto::getId, PersonDto::getUserName, (o1, o2) -> o1));
// 相反 如果Id重复取最后一个name
Map<Long, String> collect2 = objects.stream().collect(Collectors.toMap(PersonDto::getId, PersonDto::getUserName, (o1, o2) -> o2));