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 新特性:日期處理


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM