package com.shi.lambda; import java.util.Arrays; import java.util.List; import org.junit.Test; import com.shi.model.Employee; /** * 初始化案例 * @author xiaoshi * */ public class _1_FirstDomo { List<Employee> employees = Arrays.asList(new Employee("張三",12,665.23), new Employee("張三",12,789.23), new Employee("張三",15,133.23), new Employee("張三",20,7884.23), new Employee("張三",30,8784.23), new Employee("張三",40,665.23)); /** * 查詢年齡小於等於20歲的員工的信息 Lembda stream */ @Test public void getEmployeeByAge() { employees.stream() .filter((e) -> e.getAge()<20) .forEach(System.out::println); } /** * 查詢工資大於的1000的員工信息 Lembda stream */ @Test public void getEmployeeBySalary() { employees.stream() .filter((e) -> e.getSalary()>1000) .forEach(System.out::println); } }
package com.shi.lambda; import java.util.Comparator; import java.util.function.Consumer; import org.junit.Test; /** * 一 . lambda 表達式的基礎語法:JAVA8 中引用了一個新的操做符 「->」 該操做符稱爲箭頭操做符或者叫作lambda操做符 * * 箭頭操做符將lambda表達式拆封成倆部分: * 左測:lambda 表達式的參數列表 * 右側: lambda 表達式所需執行的功能,及lambda體 * * 語法格式一:無參數,無返回值 * () -> System.out.println("hello Lambda"); * * 語法格式二:有一個參數,而且無返回值 (若是是一個參數 括號能夠不寫 ) * x -> System.out.println(x); * * 語法格式三:有倆個以上的參數,有返回值,而且Lambda 體中有多條語句 * Comparator<Integer> con = (x,y) -> { System.out.println("函數式接口"); return Integer.compare(x, y); }; * * 語法格式四:有倆個以上的參數,有返回值,而且Lambda 體中有隻有一條語句 * Comparator<Integer> con = (x,y) -> Integer.compare(x, y); * * * 語法格式五: Lambda 表達式的參數列表的類型能夠省略不寫, * 由於JVM編譯器 經過上下文推斷出,數據類型,既「類型判斷」 * * 口訣: 左側遇一括號省; * 右側遇一return省; * 左側推斷類型省; * 右側多條大括號; * * 二. lambda 表達式須要「函數式接口」的支持 * 函數式接口:接口中只有一個抽象方法的接口,稱爲函數式接口 可使用@FunctionalInterface修飾(檢查接口是不是函數式接口) * * @author xiaoshi * */ public class _2_lambdaTest { //無參數,無返回值 @Test public void test1() { System.out.println("-------以前的實現方式------"); Runnable r = new Runnable() { @Override public void run() { System.out.println("hello world!"); } }; r.run(); System.out.println("-------lambda的實現方式------"); Runnable r1 = () -> System.out.println("hello lambda"); r1.run(); } //有一個參數,而且無返回值 (若是是一個參數 括號能夠不寫 ) @Test public void test2() { Consumer<String> con = x -> System.out.println(x); con.accept("像接口中添加元素"); } //有倆個以上的參數,有返回值,而且Lambda 體中有多條語句 @Test public void test3() { Comparator<Integer> con = (x,y) -> { System.out.println("函數式接口"); return Integer.compare(x, y); }; System.out.println(con.compare(10, 12)); } //語法格式四:有倆個以上的參數,有返回值,而且Lambda 體中有隻有一條語句 @Test public void test4() { Comparator<Integer> con = (x,y) -> Integer.compare(x, y); System.out.println(con.compare(10, 6)); } }
package com.shi.lambda; import java.util.UUID; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; import org.junit.Test; /** * Java8 4大核心函數式接口 * * Consumer<T> :消費型接口 (有參數,無返回值的接口) * void accept(T t); * * Supplier<T> :供給型接口(無參數,有返回值的接口) * T get(); * * Function<T,R> :函數型接口(參數T類型,返回值R類型) * R apply(T t); * * Predicate<T> : 斷言型接口 (參數 T類型,返回Boolean) * boolean test(T t); * * @author xiaoshi * */ public class _3_LambdaFunction { //Consumer<T> :消費型接口 (有參數,無返回值的接口) @Test public void test1 () { Consumer<Double> con = (m) -> System.out.println("我消費"+m+"$"); con.accept(100.0);//調用接口 } //Supplier<T> :供給型接口 (無參數,有返回值的接口) @Test public void test2() { Supplier<String> supp = () -> UUID.randomUUID().toString(); System.out.println(supp.get());//調用接口 } //Function<T,R> :函數型接口 (參數T類型,返回值R類型) @Test public void test3() { //把Double轉換成字符串輸出 Function<Double,String> fun = (item) -> item.toString(); System.out.println(fun.apply(123.334));//調用接口 } //Predicate<T> : 斷言型接口 (參數 T類型,返回Boolean) @Test public void test4() { //字符串的長度大於4則返回 Predicate<String> prd = (item) -> item.length() > 4; System.out.println(prd.test("shiye"));//調用接口 } }
package com.shi.stream; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Stream; import org.junit.Test; import com.shi.model.Employee; /** * Stream 是一個流,不改變數據源,產生一個新的數據的流 * Stream 是一個惰性求值,延遲加載的過程 * * * 一。 Stream的三個操做步驟 * * 1. 建立stream, * 2.中間操做 * 3.終止操做(終端操做 ) * * * @author xiaoshi * */ public class _4_StreamTest { //建立stream @Test public void test1() { //1. 能夠經過Collection系列集合提供的Stream(串行流) 或者 parallelStream(並行流) List<String> list = new ArrayList<>(); Stream<String> stream1 = list.stream(); //2. 經過Arrays 中的靜態方法stream() 獲取數組流 Employee[] emps = new Employee[10]; Stream<Employee> stream2 = Arrays.stream(emps); //3. 經過Stream類中的靜態方法of() Stream<String> stream3 = Stream.of("aa","bb","cc"); //4. 建立無限流(迭代) Stream<Integer> stream4 = Stream.iterate(0, (x) -> x+2); stream4.limit(5).forEach(System.out::println); //5 使用 Stream.generate() 方法 Stream.generate(() -> Math.random()) .limit(10).forEach(System.out::println); } }
package com.shi.stream; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Optional; import java.util.stream.Stream; import org.junit.Test; import com.shi.model.Employee; /** * Stream 的中間操做 * * @author xiaoshi * */ public class _5_StreamTest { List<Employee> employees = Arrays.asList(new Employee("張三",12,100.23), new Employee("李四",23,789.23), new Employee("王五",15,133.23), new Employee("趙六",8,7884.23), new Employee("田七",30,8784.23), new Employee("田七",30,8784.23), new Employee("田七",30,8784.23), new Employee("田七",30,8784.23), new Employee("劉八",40,665.23)); /** * 篩選與切片 * filter - 接收Lambda,從流中排除某些元素 * limit - 截斷流,使其元素不超過給定數量 * skip(n) - 跳過元素,返回一個扔掉了前n個元素的流,若流中元素不足n個,則返回一個空值,與limit(n)互補 * distinct - 篩選,經過流中所生成元素的HashCode() 和 equals() 去除重複元素 */ @Test public void test1() { //中間操做:不會執行任何操做 System.out.println("*********** filter ************"); Stream<Employee> stream = employees.stream() .filter((e) -> { System.out.println("遍歷到當前值"+e.getAge()); return e.getAge() > 20; }); //終止操做:一次性執行所有內容,既:「惰性求值」 stream.forEach(System.out::println); System.out.println("---------------limit----------------"); employees.stream() .filter((e) -> { System.out.println("短路!"); return e.getSalary() > 500; }) .limit(2) .forEach(System.out::println); System.out.println("***************skip distinct**************"); employees.stream() .filter((e) -> e.getSalary()>500) .skip(2) .distinct() .forEach(System.out::println); } /** * 映射 : * map - 接收lambda,將元素轉換成其餘形式或者提取信息。接收一個函數做爲參數, * 該函數會被應用到每一個元素上,並將映射成一個新的函數 * flatMap - 接收一個函數做爲參數,將流中的每一個值都換成一個流,而後把全部流鏈接成一個流 */ @Test public void test2() { List<String> list = Arrays.asList("aaa","bbb","ccc"); System.out.println("************map************"); list.stream() .map((str) -> str.toUpperCase()) .forEach(System.out::println); employees.stream() .map(Employee::getName) .forEach(System.out::println); System.out.println("************flatMap************"); } /** * 排序: * sorted() - 天然排序(comparable) * sorted(Comparator comparator) - 定製排序(Comparator) */ @Test public void test3() { List<String> list = Arrays.asList("ccc","ddd","eee","aaa","bbb"); System.out.println("------------天然排序------------"); list.stream() .sorted() .forEach(System.out::println); System.out.println("------------定製排序------------"); employees.stream() .sorted((e1,e2) -> { if(e1.getAge().equals(e2.getAge())) { return e1.getName().compareTo(e2.getName()); }else { return e1.getAge().compareTo(e2.getAge()); } }).forEach(System.out::println); } /** * 查找與匹配: * allMatch - 檢查匹配全部元素 * anyMatch - 匹配到任意一個元素 * noneMatch - 沒有匹配到任意一個元素 */ @Test public void test4() { System.out.println("-----------allMatch-----------"); boolean allMatch = employees.stream() .allMatch((e) -> { System.out.println("匹配到但前元素" + e.getAge()); return e.getAge()< 30 ; }); System.out.println(allMatch); System.out.println("-----------anyMatch-----------"); boolean anyMatch = employees.stream() .anyMatch((e) -> { System.out.println("匹配到但前元素" + e.getAge()); return e.getAge()< 30 ; }); System.out.println(anyMatch); System.out.println("-----------noneMatch-----------"); boolean noneMatch = employees.stream() .noneMatch((e) -> { System.out.println("匹配到但前元素" + e.getAge()); return e.getAge()< 30 ; }); System.out.println(noneMatch); System.out.println("-----------findFirst-----------"); Optional<Employee> findFirst = employees.stream() .sorted((e1,e2) -> e1.getAge().compareTo(e2.getAge())) .findFirst(); System.out.println(findFirst.get()); System.out.println("-----------findAny-----------"); Optional<Employee> findAny = employees.stream() .sorted((e1,e2) -> e1.getAge().compareTo(e2.getAge())) .findAny(); System.out.println(findAny.get()); System.out.println("-----------max-----------"); Optional<Employee> max = employees.stream() .max((e1,e2) -> e1.getAge().compareTo(e2.getAge())); System.out.println(max.get()); System.out.println("-----------min-----------"); Optional<Integer> min = employees.stream() .map( Employee::getAge) .min(Integer::compareTo); //這裏調用上下文中的compareTo System.out.println(min.get()); } /** * 規約 * reduce(T identity, BinaryOperator<T> accumulator)/ * reduce(BinaryOperator<T> accumulator) * - 能夠將流中的元素反覆結合起來,獲得一個值 */ @Test public void test5() { List<Integer> list = Arrays.asList(1,2,3,4,5); System.out.println("---------reduce--------"); Integer sum = list.stream() .reduce( 0 , (x,y) -> x + y ); System.out.println(sum); System.out.println("---------reduce2--------"); Optional<Double> reduce2 = employees.stream() .map(Employee::getSalary) .reduce(Double::sum); System.out.println(reduce2.get()); } /** * 收集 : * collect - 將流轉換爲其餘形式。接收一個Collector接口的實現,用於給Stream 中元素作彙總的方法 */ @Test public void test6() { System.out.println("********collect********"); Set<String> collect = employees.stream() .map(Employee::getName) .collect(Collectors.toSet()); //去除重複元素 System.out.println(collect); System.out.println("**********linkedHashSet**********"); LinkedHashSet<String> linkedHashSet = employees.stream() .map(Employee::getName) .collect(Collectors.toCollection(LinkedHashSet::new)); linkedHashSet.forEach(System.out::println); } }
package com.shi.frokjoin; import java.util.concurrent.RecursiveTask; /** * 簡單的模擬Fork/Join框架的使用 * @author xiaoshi * */ public class ForkJoinCalculate extends RecursiveTask<Long>{ /** * */ private static final long serialVersionUID = 1L; private long start; private long end; private static final long THRESHOLD = 10000; public ForkJoinCalculate(long start,long end) { this.start = start; this.end = end; } @Override protected Long compute() { long length = end - start; if(length <= THRESHOLD) { long sum = 0; for (long i = start; i <= end; i++) { sum += i; } return sum; }else { long middle = (start + end) / 2; //迭代 ForkJoinCalculate left = new ForkJoinCalculate(start, middle); left.fork(); //拆分子任務,同時壓入線程隊列 ForkJoinCalculate right = new ForkJoinCalculate(middle + 1 ,end); right.fork(); return left.join() + right.join(); } } }
package com.shi.frokjoin; import java.time.Duration; import java.time.Instant; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinTask; import java.util.stream.LongStream; import org.junit.Test; /** * 效率測試 * @author xiaoshi * */ public class TestForkJoin { /** * 使用fork/join框架進行測試用時時間 * * 數據:100000000L 10000000000L * 時間: 34毫秒 1204毫秒 */ @Test public void test1() { Instant start = Instant.now(); ForkJoinPool pool = new ForkJoinPool(); ForkJoinTask<Long> task = new ForkJoinCalculate(0,10000000000L); Long sum = pool.invoke(task); System.out.println(sum); Instant end = Instant.now(); System.out.println("耗時時間爲:" + Duration.between(start, end).toMillis() + "毫秒"); } /** * 使用單線程用時時間 * 數據:100000000L 10000000000L * 時間:425毫秒 27855毫秒 */ @Test public void test2() { Instant start = Instant.now(); Long sum = 0L; for(long i = 0;i < 10000000000L; i++) { sum += i; } System.out.println(sum); Instant end = Instant.now(); System.out.println("耗時時間爲:" + Duration.between(start, end).toMillis() + "毫秒"); } /** * 使用JAVA 8 提供的並行流 * * 數據:100000000L 10000000000L * 時間:66毫秒 825毫秒 */ @Test public void test3() { Instant start = Instant.now(); LongStream.rangeClosed(0,10000000000L) .parallel() .reduce(0, Long::sum); Instant end = Instant.now(); System.out.println("耗時時間爲:" + Duration.between(start, end).toMillis() + "毫秒"); } }
package com.shi.date; import java.time.DayOfWeek; import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.Period; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.time.temporal.TemporalAdjusters; import java.util.Set; import org.junit.Test; /** * JAVA8 日期時間的操做 * @author xiaoshi * */ public class DateTest { /** * 獲取當前時間 * LocalDate、LocalTime、LocalDateTime */ @Test public void test1() { LocalDate localDate = LocalDate.now(); System.out.println(localDate); LocalTime localTime = LocalTime.now(); System.out.println(localTime); LocalDateTime localDateTime = LocalDateTime.now(); System.out.println(localDateTime); } /** * 指定時間日期的轉化 (不能超出時間限制) */ @Test public void test2() { LocalDate localDate = LocalDate.of(2019, 5, 18); System.out.println(localDate); LocalTime localTime = LocalTime.of(18, 29, 45); System.out.println(localTime); LocalDateTime localDateTime = LocalDateTime.of(2018, 12, 1, 23, 11, 12); System.out.println(localDateTime); } /** * 日期的加減操做(+ - ) */ @Test public void test3() { LocalDate localDate = LocalDate.now(); System.out.println("當前時間:"+localDate); System.out.println("當前時間加3天:"+localDate.plusDays(3)); System.out.println("當前時間加3個月:"+localDate.plusMonths(3)); System.out.println("當前時間加3年:"+localDate.plusYears(3)); System.out.println("當前時間加2周:"+localDate.plusWeeks(2)); System.out.println("當前時間減去3天:"+localDate.minusDays(3)); System.out.println("當前時間減去3個月:"+localDate.minusMonths(3)); System.out.println("當前時間減去3年:"+localDate.minusYears(3)); System.out.println("當前時間減去2周:"+localDate.minusWeeks(2)); } /** * 獲取年月日,和時間基本判斷 */ @Test public void test4() { LocalDate localDate = LocalDate.now(); System.out.println("這個月的天數:"+localDate.getDayOfMonth()); System.out.println("今年的第幾天:"+localDate.getDayOfYear()); System.out.println("今天是周幾:"+localDate.getDayOfWeek()); System.out.println("今天是第幾月:"+localDate.getMonth()); System.out.println("今天是第幾年:"+localDate.getYear()); LocalDate plusDays = localDate.plusDays(3); LocalDate minusDays = localDate.minusDays(2); System.out.println("localDate在plusDays以前:" + localDate.isBefore(plusDays)); System.out.println("localDate在minusDays以後:" + localDate.isAfter(minusDays)); System.out.println("今年是否是潤年"+localDate.isLeapYear()); } /** * Duration 和 Period * Duration:用於計算兩個「時間」間隔 * Period:用於計算兩個「日期」間隔 */ @Test public void test5() { LocalDate localDate = LocalDate.now(); LocalDate plusDays = localDate.plusDays(10); LocalDateTime localDateTime = LocalDateTime.now(); LocalDateTime plusMinutes = localDateTime.plusMinutes(46); System.out.println("時間相差:" + Duration.between(localDateTime, plusMinutes).toMinutes() + "分鐘"); System.out.println("日期相差:" + Period.between(localDate, plusDays).getDays() + "天"); } /** * 時間矯正器 * 下一個日期的指定 */ @Test public void test6() { LocalDate nextLocalDate = LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.WEDNESDAY)); System.out.println("下一個週三的日期 : " + nextLocalDate); } /** * 格式化日期時間 */ @Test public void test7() { DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME; LocalDateTime localDateTime = LocalDateTime.now(); String now = dateTimeFormatter.format(localDateTime); System.out.println(" 根據ISO_LOCAL_DATE_TIME格式化日期 : " + now); DateTimeFormatter ofPattern = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss"); System.out.println("指定日期格式轉化 : " + ofPattern.format(localDateTime)); } /** * 獲取全部時區 */ @Test public void test8() { Set<String> set = ZoneId.getAvailableZoneIds(); set.forEach(System.out::println); } /** * ZonedDate、ZonedTime、ZonedDateTime * 獲取指定時區下的時間 */ @Test public void test9() { LocalDateTime localDateTime1 = LocalDateTime.now(ZoneId.of("America/Cuiaba")); System.out.println("America/Cuiaba時區下面的時間 : " + localDateTime1); LocalDateTime localDateTime2 = LocalDateTime.now(ZoneId.of("Asia/Shanghai")); System.out.println("Asia/Shanghai時區下的時間 : " + localDateTime2); } }