• Java 8 新特性:Lambda、Stream和日期处理


    1. Lambda

    • 简介
        Lambda表达式(Lambda Expression)是匿名函数,Lambda表达式基于数学中的λ演算得名,对应于其中的Lambda抽象(Lambda Abstraction),它是一个匿名函数,即没有函数名的函数。
    • 示例
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    import org.junit.Test;
    
    /**
     * 测试Java8 Lambda
     * 
     * @author CL
     *
     */
    public class TestLambda {
    
    	/**
    	 * 遍历
    	 */
    	@Test
    	@SuppressWarnings("serial")
    	public void print() {
    		// 1. 遍历List
    		List<Integer> list = new ArrayList<Integer>() {
    			{
    				add(1);
    				add(2);
    				add(3);
    			}
    		};
    
    		list.forEach(n -> {
    			System.out.println(n);
    		});
    
    		System.out.println("------------");
    
    		list.forEach(System.out::println);
    
    		System.out.println("------------");
    
    		// 2. 遍历Set
    		Set<Integer> set = new HashSet<Integer>() {
    			{
    				add(1);
    				add(2);
    				add(3);
    			}
    		};
    
    		set.forEach(n -> {
    			System.out.println(n);
    		});
    
    		System.out.println("------------");
    
    		set.forEach(System.out::println);
    
    		System.out.println("------------");
    
    		// 3. 遍历Map
    		Map<String, Object> map = new HashMap<String, Object>() {
    			{
    				put("id", 1);
    				put("name", "张三");
    				put("age", 18);
    			}
    		};
    
    		map.forEach((k, v) -> {
    			System.out.println(k + " -> " + v);
    		});
    	}
    
    	/**
    	 * 创建线程
    	 */
    	@Test
    	public void create() {
    		Runnable r1 = new Runnable() {
    
    			@Override
    			public void run() {
    				System.out.println("r1");
    			}
    		};
    
    		r1.run();
    
    		System.out.println("------------");
    
    		Runnable r2 = () -> {
    			System.out.println("r2");
    		};
    		r2.run();
    	}
    
    }
    

    2. Stream

    • 简介
        Stream使用一种类似于SQL语句方式来提供对Java集合运算和表达的抽象。Stream API可以使代码更加高效、干净、简洁。这种风格将要处理的元素集合看作一种流,流在管道中传输,并且可以在管道的节点上进行处理,如筛选、 排序、聚合等。
    • 示例
    import java.math.BigDecimal;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.IntSummaryStatistics;
    import java.util.List;
    import java.util.Map;
    import java.util.Random;
    import java.util.Set;
    import java.util.Stack;
    import java.util.function.Supplier;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    import org.junit.Test;
    
    /**
     * 测试Java8 Stream
     * 
     * @author CL
     *
     */
    public class TestStream {
    
    	/**
    	 * 过滤
    	 */
    	@Test
    	@SuppressWarnings("serial")
    	public void filter() {
    		List<Integer> list = new ArrayList<Integer>() {
    			{
    				add(1);
    				add(2);
    				add(2);
    				add(3);
    				add(4);
    			}
    		};
    
    		// 过滤3
    		list = list.stream().filter(n -> (n != 3)).collect(Collectors.toList());
    		list.forEach(System.out::println);
    	}
    
    	/**
    	 * 构造流
    	 */
    	@Test
    	@SuppressWarnings({ "rawtypes", "unused" })
    	public void build() {
    		// 第一种
    		Stream s1 = Stream.of("a", "b", "c");
    
    		// 第二种
    		String[] strArray = new String[] { "a", "b", "c" };
    		Stream s2 = Stream.of(strArray);
    
    		// 第三种
    		Stream s3 = Arrays.stream(strArray);
    
    		// 第四种
    		List<String> strList = Arrays.asList(strArray);
    		Stream s4 = strList.stream();
    	}
    
    	/**
    	 * 转换
    	 */
    	@Test
    	@SuppressWarnings({ "rawtypes", "unused" })
    	public void transfer() {
    		Stream<String> stream = Stream.of("a", "b", "c");
    
    		// 转换成String数组
    		String[] array = stream.toArray(String[]::new);
    
    		// 转换成String
    		String str = stream.collect(Collectors.joining(",")).toString();
    
    		// 转换成List
    		List<String> list1 = stream.collect(Collectors.toList());
    		List<String> list2 = stream.collect(Collectors.toCollection(ArrayList::new));
    
    		// 转换成Set
    		Set<String> set = stream.collect(Collectors.toSet());
    
    		// 转换成堆
    		Stack stack = stream.collect(Collectors.toCollection(Stack::new));
    	}
    
    	/**
    	 * Stream.map方法,映射元素结果(一对一)
    	 */
    	@Test
    	@SuppressWarnings("serial")
    	public void map() {
    		// 转换大写
    		List<String> list = Arrays.asList("a", "b", "c");
    		list = list.stream().map(String::toUpperCase).collect(Collectors.toList());
    		list.forEach(System.out::println);
    
    		System.out.println("------------");
    
    		// 转换数据类型
    		List<String> list2 = Arrays.asList("1", "2", "3");
    		List<Integer> list3 = list2.stream().map(Integer::valueOf).collect(Collectors.toList());
    		list3.forEach(System.out::println);
    
    		System.out.println("------------");
    
    		// 计算结果
    		List<Integer> list4 = Arrays.asList(1, 2, 3);
    		list4 = list4.stream().map(n -> (n * 2)).collect(Collectors.toList());
    		list4.forEach(System.out::println);
    
    		System.out.println("------------");
    
    		// 计算除去3之后的和及个数
    		List<Integer> list5 = Arrays.asList(1, 2, 3, 4, 5);
    		int sum = list5.stream().filter(n -> (n != 3)).mapToInt(n -> n).sum();
    		long count = list5.stream().filter(n -> (n != 3)).mapToInt(n -> n).count();
    		System.out.println(sum);
    		System.out.println(count);
    
    		System.out.println("------------");
    
    		// 统计员工的工资和
    		List<User> userList = new ArrayList<User>() {
    			{
    				add(new User(1, "张三", 1203.12));
    				add(new User(2, "李四", 2856.43));
    				add(new User(3, "王五", 947.63));
    			}
    		};
    		double sum2 = userList.stream().mapToDouble(u -> u.getSalary()).sum();
    		System.out.println(sum2);
    
    		System.out.println("------------");
    
    		// 统计工资大于1000的人数
    		long count2 = userList.stream().filter(u -> (u.getSalary() > 1000)).mapToInt(u -> u.getId()).count();
    		System.out.println(count2);
    	}
    
    	/**
    	 * Stream.flatMap方法,映射元素结果(一对多)
    	 */
    	@Test
    	@SuppressWarnings("serial")
    	public void flatMap() {
    		List<String> list = new ArrayList<String>() {
    			{
    				add("Knowledge is power");
    			}
    		};
    
    		// 分割单词
    		list = list.stream().flatMap(str -> Stream.of(str.split(" "))).filter(s -> s.length() > 0)
    				.collect(Collectors.toList());
    		list.forEach(System.out::println);
    	}
    
    	/**
    	 * 限制
    	 */
    	@Test
    	public void limit() {
    		List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
    
    		// 取前3条数据
    		List<Integer> list1 = list.stream().limit(3).collect(Collectors.toList());
    		list1.forEach(System.out::println);
    
    		System.out.println("------------");
    
    		// 从第2条数据开始取3条数据
    		List<Integer> list2 = list.stream().skip(2).limit(3).collect(Collectors.toList());
    		list2.forEach(System.out::println);
    	}
    
    	/**
    	 * 排序
    	 */
    	@Test
    	@SuppressWarnings("serial")
    	public void sort() {
    		List<Integer> list = Arrays.asList(4, 2, 6, 1, 7, 3, 8, 5);
    
    		// 默认升序
    		List<Integer> list1 = list.stream().sorted().collect(Collectors.toList());
    		list1.forEach(System.out::println);
    
    		System.out.println("------------");
    
    		// 按照员工工资降序排序
    		List<User> userList = new ArrayList<User>() {
    			{
    				add(new User(1, "张三", 1203.12));
    				add(new User(2, "李四", 2856.43));
    				add(new User(3, "王五", 947.63));
    			}
    		};
    
    		List<User> list2 = userList.stream().sorted((u1, u2) -> (u2.getSalary().compareTo(u1.getSalary())))
    				.collect(Collectors.toList());
    		list2.forEach(System.out::println);
    	}
    
    	/**
    	 * Stream.peek方法,返回新的Stream
    	 */
    	@Test
    	public void peek() {
    		List<Integer> list = Arrays.asList(1, 2, 2, 3, 4);
    
    		// 过滤掉不等于2和大于3的数后计算和
    		int sum = list.stream().filter(n -> (n != 2)).peek(n -> {
    			// 中间处理
    		}).filter(n -> (n > 3)).peek(n -> {
    			// 中间处理
    		}).mapToInt(n -> n).sum();
    		System.out.println(sum);
    	}
    
    	/**
    	 * 并行流
    	 */
    	@Test
    	public void parallelStream() {
    		List<Integer> list = Arrays.asList(1, 2, 2, 3, 4);
    
    		// 统计2的个数
    		long count = list.parallelStream().filter(n -> (n == 2)).count();
    		System.out.println(count);
    	}
    
    	/**
    	 * 最大、最小、去重
    	 */
    	@Test
    	public void maxAndMinAndDistinct() {
    		List<Integer> list = Arrays.asList(1, 2, 2, 3, 4);
    
    		// 最大值
    		Integer max = list.stream().max((a, b) -> a.compareTo(b)).get();
    		System.out.println(max);
    
    		System.out.println("------------");
    
    		// 最小值
    		Integer min = list.stream().min((a, b) -> a.compareTo(b)).get();
    		System.out.println(min);
    
    		System.out.println("------------");
    
    		// 去重
    		list = list.stream().distinct().collect(Collectors.toList());
    		list.forEach(System.out::println);
    	}
    
    	/**
    	 * 匹配<br/>
    	 * allMatch:全部元素符合则返回 true <br/>
    	 * anyMatch:只要有一个元素符合则返回 true <br/>
    	 * noneMatch:没有一个元素符合则返回 true <br/>
    	 */
    	@Test
    	@SuppressWarnings("serial")
    	public void match() {
    		List<User> userList = new ArrayList<User>() {
    			{
    				add(new User(1, "张三", 1203.12));
    				add(new User(2, "李四", 2856.43));
    				add(new User(3, "王五", 947.63));
    			}
    		};
    
    		// 判断所有人的工资都大于2000
    		boolean allMatch = userList.stream().allMatch(u -> (u.getSalary() > 2000));
    		System.out.println(allMatch);
    
    		System.out.println("------------");
    
    		boolean anyMatch = userList.stream().anyMatch(u -> (u.getSalary() > 2000));
    		System.out.println(anyMatch);
    
    		System.out.println("------------");
    
    		boolean noneMatch = userList.stream().noneMatch(u -> (u.getSalary() > 2000));
    		System.out.println(noneMatch);
    	}
    
    	/**
    	 * reduce和Stream组合使用
    	 */
    	@Test
    	public void reduce() {
    		// 拼接
    		List<String> list = Arrays.asList("Knowledge", " ", "is", " ", "power");
    		String str = list.stream().reduce("", String::concat);
    		System.out.println(str);
    
    		System.out.println("------------");
    
    		// 求和
    		List<Integer> list2 = Arrays.asList(1, 2, 3, 4);
    		Integer sum = list2.stream().reduce(Integer::sum).get();
    		System.out.println(sum);
    	}
    
    	/**
    	 * Stream.iterate方法
    	 */
    	@Test
    	public void iterate() {
    		// 生成等差2的数列
    		Stream.iterate(2, n -> n + 2).limit(5).forEach(System.out::println);
    	}
    
    	/**
    	 * 分组排序和分区排序 <br/>
    	 * groupingBy:分组排序 <br/>
    	 * partitioningBy:分区排序 <br/>
    	 */
    	@Test
    	@SuppressWarnings("serial")
    	public void groupyAndPartition() {
    		List<User> userList = new ArrayList<User>() {
    			{
    				add(new User(1, "张三", 1203.12));
    				add(new User(2, "李四", 2856.43));
    				add(new User(3, "王五", 947.63));
    				add(new User(3, "张六", 2417.05));
    			}
    		};
    
    		// 分组排序
    		Map<String, List<User>> resultMap = userList.stream().collect(Collectors.groupingBy(User::getName));
    		for (Map.Entry<String, List<User>> entry : resultMap.entrySet()) {
    			entry.getValue().forEach(v -> System.out.println(entry.getKey() + " -> " + v));
    		}
    
    		System.out.println("------------");
    
    		// 分区排序
    		Map<Boolean, List<User>> resultMap2 = userList.stream()
    				.collect(Collectors.partitioningBy(u -> (u.getSalary() > 2000)));
    		// 大于2000
    		System.out.println(resultMap2.get(true));
    
    		System.out.println("------------");
    
    		// 不大于2000
    		System.out.println(resultMap2.get(false));
    	}
    
    	/**
    	 * 收集统计
    	 */
    	@Test
    	public void summaryStatistics() {
    		List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
    		IntSummaryStatistics summaryStatistics = list.stream().mapToInt(n -> n).summaryStatistics();
    
    		// 最大值
    		System.out.println(summaryStatistics.getMax());
    
    		// 最小值
    		System.out.println(summaryStatistics.getMin());
    
    		// 求和
    		System.out.println(summaryStatistics.getSum());
    
    		// 平均值
    		System.out.println(summaryStatistics.getAverage());
    
    		// 数量
    		System.out.println(summaryStatistics.getCount());
    	}
    
    	/**
    	 * 自定义流
    	 */
    	@Test
    	public void supplier() {
    		/**
    		 * 自定义用户流处理类
    		 * 
    		 * @author CL
    		 *
    		 */
    		class UserSupplier implements Supplier<User> {
    			private Integer index = 1;
    			private String[] names = new String[] { "张三", "李四", "王五" };
    			private Random random = new Random();
    
    			@Override
    			public User get() {
    				return new User(index++, names[index - 2],
    						new BigDecimal(random.nextDouble() * 1000).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
    			}
    
    		}
    		Stream.generate(new UserSupplier()).limit(3).collect(Collectors.toList()).forEach(System.out::println);
    	}
    }
    
    /**
     * 用户类
     * 
     * @author CL
     *
     */
    class User {
    	/**
    	 * ID
    	 */
    	private Integer id;
    
    	/**
    	 * 用户名
    	 */
    	private String name;
    
    	/**
    	 * 工资
    	 */
    	private Double salary;
    
    	public User() {
    		super();
    	}
    
    	public User(Integer id, String name) {
    		super();
    		this.id = id;
    		this.name = name;
    	}
    
    	public User(Integer id, String name, Double salary) {
    		super();
    		this.id = id;
    		this.name = name;
    		this.salary = salary;
    	}
    
    	public Integer getId() {
    		return id;
    	}
    
    	public void setId(Integer id) {
    		this.id = id;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public Double getSalary() {
    		return salary;
    	}
    
    	public void setSalary(Double salary) {
    		this.salary = salary;
    	}
    
    	@Override
    	public String toString() {
    		return "User [id=" + id + ", name=" + name + ", salary=" + salary + "]";
    	}
    }
    
    

    3. 日期处理

      Java 8 新特性:日期处理

  • 相关阅读:
    数值微分(数学)(组合数)
    破冰派对(搜索)
    [NOIP2017]宝藏
    [NOIP2013]华容道
    收集邮票(数学期望)
    序列(DP)(组合数)
    luogu1357花园(矩阵运算)(状压DP)
    游戏(期望)
    [NOIP2012]疫情控制
    [NOIP2012] 开车旅行
  • 原文地址:https://www.cnblogs.com/cao-lei/p/13571622.html
Copyright © 2020-2023  润新知