submit = executorService.submit(() -> {
15 | TimeUnit.SECONDS.sleep(3);
16 | return 100;
17 | });
18 |
19 | // try {
20 | // Integer result = submit.get();
21 | // System.out.println(result);
22 | // } catch (InterruptedException e) {
23 | // e.printStackTrace();
24 | // } catch (ExecutionException e) {
25 | // e.printStackTrace();
26 | // }
27 |
28 | while(!submit.isDone()){
29 | try {
30 | TimeUnit.MILLISECONDS.sleep(100);
31 | } catch (InterruptedException e) {
32 | e.printStackTrace();
33 | }
34 | }
35 | Integer result = submit.get();
36 | System.out.println(result);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/java8-concurrent/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | learn-java8
7 | io.github.biezhi
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | java8-concurrent
13 |
14 |
--------------------------------------------------------------------------------
/java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Atomic1.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.concurrent;
2 |
3 | import java.util.concurrent.ExecutorService;
4 | import java.util.concurrent.Executors;
5 | import java.util.concurrent.atomic.AtomicInteger;
6 | import java.util.stream.IntStream;
7 |
8 | /**
9 | * 原子变量
10 | *
11 | * AtomicInteger
12 | * LongAdder
13 | * LongAccumulator
14 | *
15 | * @author biezhi
16 | * @date 2018/3/5
17 | */
18 | public class Atomic1 {
19 |
20 | private static final int NUM_INCREMENTS = 1000;
21 |
22 | private static AtomicInteger atomicInt = new AtomicInteger(0);
23 |
24 | public static void main(String[] args) {
25 | testIncrement();
26 | // testAccumulate();
27 | // testUpdate();
28 | }
29 |
30 | private static void testUpdate() {
31 | atomicInt.set(0);
32 |
33 | ExecutorService executor = Executors.newFixedThreadPool(2);
34 |
35 | IntStream.range(0, NUM_INCREMENTS)
36 | .forEach(i -> {
37 | Runnable task = () ->
38 | atomicInt.updateAndGet(n -> n + 2);
39 | executor.submit(task);
40 | });
41 |
42 | ConcurrentUtils.stop(executor);
43 |
44 | System.out.format("Update: %d\n", atomicInt.get());
45 | }
46 |
47 | private static void testAccumulate() {
48 | atomicInt.set(0);
49 |
50 | ExecutorService executor = Executors.newFixedThreadPool(2);
51 |
52 | IntStream.range(0, NUM_INCREMENTS)
53 | .forEach(i -> {
54 | Runnable task = () ->
55 | atomicInt.accumulateAndGet(i, (n, m) -> n + m);
56 | executor.submit(task);
57 | });
58 |
59 | ConcurrentUtils.stop(executor);
60 |
61 | System.out.format("Accumulate: %d\n", atomicInt.get());
62 | }
63 |
64 | private static void testIncrement() {
65 | atomicInt.set(0);
66 |
67 | ExecutorService executor = Executors.newFixedThreadPool(2);
68 |
69 | IntStream.range(0, NUM_INCREMENTS)
70 | .forEach(i -> executor.submit(atomicInt::incrementAndGet));
71 |
72 | ConcurrentUtils.stop(executor);
73 |
74 | System.out.format("Increment: Expected=%d; Is=%d\n", NUM_INCREMENTS, atomicInt.get());
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/ConcurrentHashMap1.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.concurrent;
2 |
3 | import java.util.concurrent.ConcurrentHashMap;
4 | import java.util.concurrent.ForkJoinPool;
5 |
6 | public class ConcurrentHashMap1 {
7 |
8 | public static void main(String[] args) {
9 | System.out.println("Parallelism: " + ForkJoinPool.getCommonPoolParallelism());
10 |
11 | testForEach();
12 | // testSearch();
13 | // testReduce();
14 | }
15 |
16 | private static void testReduce() {
17 | ConcurrentHashMap map = new ConcurrentHashMap<>();
18 | map.putIfAbsent("foo", "bar");
19 | map.putIfAbsent("han", "solo");
20 | map.putIfAbsent("r2", "d2");
21 | map.putIfAbsent("c3", "p0");
22 |
23 | String reduced = map.reduce(1, (key, value) -> key + "=" + value,
24 | (s1, s2) -> s1 + ", " + s2);
25 |
26 | System.out.println(reduced);
27 | }
28 |
29 | private static void testSearch() {
30 | ConcurrentHashMap map = new ConcurrentHashMap<>();
31 | map.putIfAbsent("foo", "bar");
32 | map.putIfAbsent("han", "solo");
33 | map.putIfAbsent("r2", "d2");
34 | map.putIfAbsent("c3", "p0");
35 |
36 | System.out.println("\nsearch()\n");
37 |
38 | String result1 = map.search(1, (key, value) -> {
39 | System.out.println(Thread.currentThread().getName());
40 | if (key.equals("foo") && value.equals("bar")) {
41 | return "foobar";
42 | }
43 | return null;
44 | });
45 |
46 | System.out.println(result1);
47 |
48 | System.out.println("\nsearchValues()\n");
49 |
50 | String result2 = map.searchValues(1, value -> {
51 | System.out.println(Thread.currentThread().getName());
52 | if (value.length() > 3) {
53 | return value;
54 | }
55 | return null;
56 | });
57 |
58 | System.out.println(result2);
59 | }
60 |
61 | private static void testForEach() {
62 | ConcurrentHashMap map = new ConcurrentHashMap<>();
63 | map.putIfAbsent("foo", "bar");
64 | map.putIfAbsent("han", "solo");
65 | map.putIfAbsent("r2", "d2");
66 | map.putIfAbsent("c3", "p0");
67 |
68 | map.forEach(1, (key, value) -> System.out.printf("key: %s; value: %s; thread: %s\n", key, value, Thread.currentThread().getName()));
69 | // map.forEach(5, (key, value) -> System.out.printf("key: %s; value: %s; thread: %s\n", key, value, Thread.currentThread().getName()));
70 |
71 | System.out.println(map.mappingCount());
72 | }
73 |
74 | }
--------------------------------------------------------------------------------
/java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/ConcurrentUtils.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.concurrent;
2 |
3 | import java.util.concurrent.ExecutorService;
4 | import java.util.concurrent.TimeUnit;
5 |
6 | /**
7 | * 并发工具类
8 | *
9 | * @author biezhi
10 | * @date 2018/3/11
11 | */
12 | public class ConcurrentUtils {
13 |
14 | public static void stop(ExecutorService executor) {
15 | try {
16 | executor.shutdown();
17 | executor.awaitTermination(60, TimeUnit.SECONDS);
18 | }
19 | catch (InterruptedException e) {
20 | System.err.println("termination interrupted");
21 | }
22 | finally {
23 | if (!executor.isTerminated()) {
24 | System.err.println("killing non-finished tasks");
25 | }
26 | executor.shutdownNow();
27 | }
28 | }
29 |
30 | public static void sleep(int seconds) {
31 | try {
32 | TimeUnit.SECONDS.sleep(seconds);
33 | } catch (InterruptedException e) {
34 | throw new IllegalStateException(e);
35 | }
36 | }
37 |
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Executors1.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.concurrent;
2 |
3 | import java.util.concurrent.ExecutorService;
4 | import java.util.concurrent.Executors;
5 | import java.util.concurrent.TimeUnit;
6 |
7 | public class Executors1 {
8 |
9 | public static void main(String[] args) {
10 | test1(3);
11 | // test1(7);
12 | }
13 |
14 | private static void test1(long seconds) {
15 | ExecutorService executor = Executors.newSingleThreadExecutor();
16 | executor.submit(() -> {
17 | try {
18 | TimeUnit.SECONDS.sleep(seconds);
19 | String name = Thread.currentThread().getName();
20 | System.out.println("task finished: " + name);
21 | } catch (InterruptedException e) {
22 | System.err.println("task interrupted");
23 | }
24 | });
25 | stop(executor);
26 | }
27 |
28 | static void stop(ExecutorService executor) {
29 | try {
30 | System.out.println("attempt to shutdown executor");
31 | executor.shutdown();
32 | executor.awaitTermination(5, TimeUnit.SECONDS);
33 | } catch (InterruptedException e) {
34 | System.err.println("termination interrupted");
35 | } finally {
36 | if (!executor.isTerminated()) {
37 | System.err.println("killing non-finished tasks");
38 | }
39 | executor.shutdownNow();
40 | System.out.println("shutdown finished");
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Executors2.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.concurrent;
2 |
3 | import java.util.concurrent.*;
4 |
5 | public class Executors2 {
6 |
7 | public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
8 | test1();
9 | // test2();
10 | // test3();
11 | }
12 |
13 | private static void test3() throws InterruptedException, ExecutionException, TimeoutException {
14 | ExecutorService executor = Executors.newFixedThreadPool(1);
15 |
16 | Future future = executor.submit(() -> {
17 | try {
18 | TimeUnit.SECONDS.sleep(2);
19 | return 123;
20 | } catch (InterruptedException e) {
21 | throw new IllegalStateException("task interrupted", e);
22 | }
23 | });
24 |
25 | future.get(1, TimeUnit.SECONDS);
26 | }
27 |
28 | private static void test2() throws InterruptedException, ExecutionException {
29 | ExecutorService executor = Executors.newFixedThreadPool(1);
30 |
31 | Future future = executor.submit(() -> {
32 | try {
33 | TimeUnit.SECONDS.sleep(1);
34 | return 123;
35 | } catch (InterruptedException e) {
36 | throw new IllegalStateException("task interrupted", e);
37 | }
38 | });
39 |
40 | executor.shutdownNow();
41 | future.get();
42 | }
43 |
44 | private static void test1() throws InterruptedException, ExecutionException {
45 | ExecutorService executor = Executors.newFixedThreadPool(1);
46 |
47 | Future future = executor.submit(() -> {
48 | try {
49 | TimeUnit.SECONDS.sleep(1);
50 | return 123;
51 | } catch (InterruptedException e) {
52 | throw new IllegalStateException("task interrupted", e);
53 | }
54 | });
55 |
56 | System.out.println("future done: " + future.isDone());
57 |
58 | Integer result = future.get();
59 |
60 | System.out.println("future done: " + future.isDone());
61 | System.out.print("result: " + result);
62 |
63 | executor.shutdownNow();
64 | }
65 |
66 | }
--------------------------------------------------------------------------------
/java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Executors3.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.concurrent;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 | import java.util.concurrent.*;
6 |
7 | public class Executors3 {
8 |
9 | public static void main(String[] args) throws InterruptedException, ExecutionException {
10 | test1();
11 | // test2();
12 | // test3();
13 |
14 | // test4();
15 | // test5();
16 | }
17 |
18 | private static void test5() throws InterruptedException, ExecutionException {
19 | ExecutorService executor = Executors.newWorkStealingPool();
20 |
21 | List> callables = Arrays.asList(
22 | callable("task1", 2),
23 | callable("task2", 1),
24 | callable("task3", 3));
25 |
26 | String result = executor.invokeAny(callables);
27 | System.out.println(result);
28 |
29 | executor.shutdown();
30 | }
31 |
32 | private static Callable callable(String result, long sleepSeconds) {
33 | return () -> {
34 | TimeUnit.SECONDS.sleep(sleepSeconds);
35 | return result;
36 | };
37 | }
38 |
39 | private static void test4() throws InterruptedException {
40 | ExecutorService executor = Executors.newWorkStealingPool();
41 |
42 | List> callables = Arrays.asList(
43 | () -> "task1",
44 | () -> "task2",
45 | () -> "task3");
46 |
47 | executor.invokeAll(callables)
48 | .stream()
49 | .map(future -> {
50 | try {
51 | return future.get();
52 | } catch (Exception e) {
53 | throw new IllegalStateException(e);
54 | }
55 | })
56 | .forEach(System.out::println);
57 |
58 | executor.shutdown();
59 | }
60 |
61 | private static void test3() {
62 | ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
63 |
64 | Runnable task = () -> {
65 | try {
66 | TimeUnit.SECONDS.sleep(2);
67 | System.out.println("Scheduling: " + System.nanoTime());
68 | } catch (InterruptedException e) {
69 | System.err.println("task interrupted");
70 | }
71 | };
72 |
73 | executor.scheduleWithFixedDelay(task, 0, 1, TimeUnit.SECONDS);
74 | }
75 |
76 | private static void test2() {
77 | ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
78 | Runnable task = () -> System.out.println("Scheduling: " + System.nanoTime());
79 | int initialDelay = 0;
80 | int period = 1;
81 | executor.scheduleAtFixedRate(task, initialDelay, period, TimeUnit.SECONDS);
82 | }
83 |
84 | private static void test1() throws InterruptedException {
85 | ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
86 |
87 | Runnable task = () -> System.out.println("Scheduling: " + System.nanoTime());
88 | int delay = 3;
89 | ScheduledFuture> future = executor.schedule(task, delay, TimeUnit.SECONDS);
90 |
91 | TimeUnit.MILLISECONDS.sleep(1337);
92 |
93 | long remainingDelay = future.getDelay(TimeUnit.MILLISECONDS);
94 | System.out.printf("Remaining Delay: %sms\n", remainingDelay);
95 | }
96 |
97 | }
--------------------------------------------------------------------------------
/java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Lock1.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.concurrent;
2 |
3 | import java.util.concurrent.ExecutorService;
4 | import java.util.concurrent.Executors;
5 | import java.util.concurrent.locks.ReentrantLock;
6 | import java.util.stream.IntStream;
7 |
8 | public class Lock1 {
9 |
10 | private static final int NUM_INCREMENTS = 10000;
11 |
12 | private static ReentrantLock lock = new ReentrantLock();
13 |
14 | private static int count = 0;
15 |
16 | private static void increment() {
17 | lock.lock();
18 | try {
19 | count++;
20 | } finally {
21 | lock.unlock();
22 | }
23 | }
24 |
25 | public static void main(String[] args) {
26 | testLock();
27 | }
28 |
29 | private static void testLock() {
30 | count = 0;
31 |
32 | ExecutorService executor = Executors.newFixedThreadPool(2);
33 |
34 | IntStream.range(0, NUM_INCREMENTS)
35 | .forEach(i -> executor.submit(Lock1::increment));
36 |
37 | ConcurrentUtils.stop(executor);
38 |
39 | System.out.println(count);
40 | }
41 |
42 | }
--------------------------------------------------------------------------------
/java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Lock2.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.concurrent;
2 |
3 | import java.util.concurrent.ExecutorService;
4 | import java.util.concurrent.Executors;
5 | import java.util.concurrent.locks.ReentrantLock;
6 |
7 | public class Lock2 {
8 |
9 | public static void main(String[] args) {
10 | ExecutorService executor = Executors.newFixedThreadPool(2);
11 |
12 | ReentrantLock lock = new ReentrantLock();
13 |
14 | executor.submit(() -> {
15 | lock.lock();
16 | try {
17 | ConcurrentUtils.sleep(1);
18 | } finally {
19 | lock.unlock();
20 | }
21 | });
22 |
23 | executor.submit(() -> {
24 | System.out.println("Locked: " + lock.isLocked());
25 | System.out.println("Held by me: " + lock.isHeldByCurrentThread());
26 | boolean locked = lock.tryLock();
27 | System.out.println("Lock acquired: " + locked);
28 | });
29 |
30 | ConcurrentUtils.stop(executor);
31 | }
32 |
33 | }
--------------------------------------------------------------------------------
/java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Lock3.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.concurrent;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | import java.util.concurrent.ExecutorService;
6 | import java.util.concurrent.Executors;
7 | import java.util.concurrent.locks.ReadWriteLock;
8 | import java.util.concurrent.locks.ReentrantReadWriteLock;
9 |
10 | public class Lock3 {
11 |
12 | public static void main(String[] args) {
13 | ExecutorService executor = Executors.newFixedThreadPool(2);
14 |
15 | Map map = new HashMap<>();
16 |
17 | ReadWriteLock lock = new ReentrantReadWriteLock();
18 |
19 | executor.submit(() -> {
20 | lock.writeLock().lock();
21 | try {
22 | ConcurrentUtils.sleep(1);
23 | map.put("foo", "bar");
24 | } finally {
25 | lock.writeLock().unlock();
26 | }
27 | });
28 |
29 | Runnable readTask = () -> {
30 | lock.readLock().lock();
31 | try {
32 | System.out.println(map.get("foo"));
33 | ConcurrentUtils.sleep(1);
34 | } finally {
35 | lock.readLock().unlock();
36 | }
37 | };
38 | executor.submit(readTask);
39 | executor.submit(readTask);
40 |
41 | ConcurrentUtils.stop(executor);
42 | }
43 |
44 | }
--------------------------------------------------------------------------------
/java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Lock4.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.concurrent;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | import java.util.concurrent.ExecutorService;
6 | import java.util.concurrent.Executors;
7 | import java.util.concurrent.locks.StampedLock;
8 |
9 | public class Lock4 {
10 |
11 | public static void main(String[] args) {
12 | ExecutorService executor = Executors.newFixedThreadPool(2);
13 |
14 | Map map = new HashMap<>();
15 |
16 | StampedLock lock = new StampedLock();
17 |
18 | executor.submit(() -> {
19 | long stamp = lock.writeLock();
20 | try {
21 | ConcurrentUtils.sleep(1);
22 | map.put("foo", "bar");
23 | } finally {
24 | lock.unlockWrite(stamp);
25 | }
26 | });
27 |
28 | Runnable readTask = () -> {
29 | long stamp = lock.readLock();
30 | try {
31 | System.out.println(map.get("foo"));
32 | ConcurrentUtils.sleep(1);
33 | } finally {
34 | lock.unlockRead(stamp);
35 | }
36 | };
37 | executor.submit(readTask);
38 | executor.submit(readTask);
39 |
40 | ConcurrentUtils.stop(executor);
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Lock5.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.concurrent;
2 |
3 | import java.util.concurrent.ExecutorService;
4 | import java.util.concurrent.Executors;
5 | import java.util.concurrent.locks.StampedLock;
6 |
7 | public class Lock5 {
8 |
9 | public static void main(String[] args) {
10 | ExecutorService executor = Executors.newFixedThreadPool(2);
11 |
12 | StampedLock lock = new StampedLock();
13 |
14 | executor.submit(() -> {
15 | long stamp = lock.tryOptimisticRead();
16 | try {
17 | System.out.println("Optimistic Lock Valid: " + lock.validate(stamp));
18 | ConcurrentUtils.sleep(1);
19 | System.out.println("Optimistic Lock Valid: " + lock.validate(stamp));
20 | ConcurrentUtils.sleep(2);
21 | System.out.println("Optimistic Lock Valid: " + lock.validate(stamp));
22 | } finally {
23 | lock.unlock(stamp);
24 | }
25 | });
26 |
27 | executor.submit(() -> {
28 | long stamp = lock.writeLock();
29 | try {
30 | System.out.println("Write Lock acquired");
31 | ConcurrentUtils.sleep(2);
32 | } finally {
33 | lock.unlock(stamp);
34 | System.out.println("Write done");
35 | }
36 | });
37 |
38 | ConcurrentUtils.stop(executor);
39 | }
40 |
41 | }
--------------------------------------------------------------------------------
/java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Lock6.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.concurrent;
2 |
3 | import java.util.concurrent.ExecutorService;
4 | import java.util.concurrent.Executors;
5 | import java.util.concurrent.locks.StampedLock;
6 |
7 | public class Lock6 {
8 |
9 | private static int count = 0;
10 |
11 | public static void main(String[] args) {
12 | ExecutorService executor = Executors.newFixedThreadPool(2);
13 |
14 | StampedLock lock = new StampedLock();
15 |
16 | executor.submit(() -> {
17 | long stamp = lock.readLock();
18 | try {
19 | if (count == 0) {
20 | stamp = lock.tryConvertToWriteLock(stamp);
21 | if (stamp == 0L) {
22 | System.out.println("Could not convert to write lock");
23 | stamp = lock.writeLock();
24 | }
25 | count = 23;
26 | }
27 | System.out.println(count);
28 | } finally {
29 | lock.unlock(stamp);
30 | }
31 | });
32 |
33 | ConcurrentUtils.stop(executor);
34 | }
35 |
36 | }
--------------------------------------------------------------------------------
/java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/LongAccumulator1.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.concurrent;
2 |
3 | import java.util.concurrent.ExecutorService;
4 | import java.util.concurrent.Executors;
5 | import java.util.concurrent.atomic.LongAccumulator;
6 | import java.util.function.LongBinaryOperator;
7 | import java.util.stream.IntStream;
8 |
9 | public class LongAccumulator1 {
10 |
11 | public static void main(String[] args) {
12 | testAccumulate();
13 | }
14 |
15 | private static void testAccumulate() {
16 | LongBinaryOperator op = (x, y) -> 2 * x + y;
17 | LongAccumulator accumulator = new LongAccumulator(op, 1L);
18 |
19 | ExecutorService executor = Executors.newFixedThreadPool(2);
20 |
21 | IntStream.range(0, 10)
22 | .forEach(i -> executor.submit(() -> accumulator.accumulate(i)));
23 |
24 | ConcurrentUtils.stop(executor);
25 |
26 | System.out.format("Add: %d\n", accumulator.getThenReset());
27 | }
28 | }
--------------------------------------------------------------------------------
/java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/LongAdder1.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.concurrent;
2 |
3 | import java.util.concurrent.ExecutorService;
4 | import java.util.concurrent.Executors;
5 | import java.util.concurrent.atomic.LongAdder;
6 | import java.util.stream.IntStream;
7 |
8 | public class LongAdder1 {
9 |
10 | private static final int NUM_INCREMENTS = 10000;
11 |
12 | private static LongAdder adder = new LongAdder();
13 |
14 | public static void main(String[] args) {
15 | testIncrement();
16 | testAdd();
17 | }
18 |
19 | private static void testAdd() {
20 | ExecutorService executor = Executors.newFixedThreadPool(2);
21 |
22 | IntStream.range(0, NUM_INCREMENTS)
23 | .forEach(i -> executor.submit(() -> adder.add(2)));
24 |
25 | ConcurrentUtils.stop(executor);
26 |
27 | System.out.format("Add: %d\n", adder.sumThenReset());
28 | }
29 |
30 | private static void testIncrement() {
31 | ExecutorService executor = Executors.newFixedThreadPool(2);
32 |
33 | IntStream.range(0, NUM_INCREMENTS)
34 | .forEach(i -> executor.submit(adder::increment));
35 |
36 | ConcurrentUtils.stop(executor);
37 |
38 | System.out.format("Increment: Expected=%d; Is=%d\n", NUM_INCREMENTS, adder.sumThenReset());
39 | }
40 | }
--------------------------------------------------------------------------------
/java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Semaphore1.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.concurrent;
2 |
3 | import java.util.concurrent.ExecutorService;
4 | import java.util.concurrent.Executors;
5 | import java.util.concurrent.Semaphore;
6 | import java.util.concurrent.TimeUnit;
7 | import java.util.stream.IntStream;
8 |
9 | public class Semaphore1 {
10 |
11 | private static final int NUM_INCREMENTS = 10000;
12 |
13 | private static Semaphore semaphore = new Semaphore(1);
14 |
15 | private static int count = 0;
16 |
17 | public static void main(String[] args) {
18 | testIncrement();
19 | }
20 |
21 | private static void testIncrement() {
22 | ExecutorService executor = Executors.newFixedThreadPool(2);
23 |
24 | IntStream.range(0, NUM_INCREMENTS)
25 | .forEach(i -> executor.submit(Semaphore1::increment));
26 |
27 | ConcurrentUtils.stop(executor);
28 |
29 | System.out.println("Increment: " + count);
30 | }
31 |
32 | private static void increment() {
33 | boolean permit = false;
34 | try {
35 | permit = semaphore.tryAcquire(5, TimeUnit.SECONDS);
36 | count++;
37 | } catch (InterruptedException e) {
38 | throw new RuntimeException("could not increment");
39 | } finally {
40 | if (permit) {
41 | semaphore.release();
42 | }
43 | }
44 | }
45 |
46 | }
--------------------------------------------------------------------------------
/java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Semaphore2.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.concurrent;
2 |
3 | import java.util.concurrent.ExecutorService;
4 | import java.util.concurrent.Executors;
5 | import java.util.concurrent.Semaphore;
6 | import java.util.concurrent.TimeUnit;
7 | import java.util.stream.IntStream;
8 |
9 | public class Semaphore2 {
10 |
11 | private static Semaphore semaphore = new Semaphore(5);
12 |
13 | public static void main(String[] args) {
14 | ExecutorService executor = Executors.newFixedThreadPool(10);
15 |
16 | IntStream.range(0, 10)
17 | .forEach(i -> executor.submit(Semaphore2::doWork));
18 |
19 | ConcurrentUtils.stop(executor);
20 | }
21 |
22 | private static void doWork() {
23 | boolean permit = false;
24 | try {
25 | permit = semaphore.tryAcquire(1, TimeUnit.SECONDS);
26 | if (permit) {
27 | System.out.println("Semaphore acquired");
28 | ConcurrentUtils.sleep(5);
29 | } else {
30 | System.out.println("Could not acquire semaphore");
31 | }
32 | } catch (InterruptedException e) {
33 | throw new IllegalStateException(e);
34 | } finally {
35 | if (permit) {
36 | semaphore.release();
37 | }
38 | }
39 | }
40 |
41 | }
--------------------------------------------------------------------------------
/java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Synchronized1.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.concurrent;
2 |
3 | import java.util.concurrent.ExecutorService;
4 | import java.util.concurrent.Executors;
5 | import java.util.stream.IntStream;
6 |
7 | public class Synchronized1 {
8 |
9 | private static final int NUM_INCREMENTS = 10000;
10 |
11 | private static int count = 0;
12 |
13 | public static void main(String[] args) {
14 | testSyncIncrement();
15 | testNonSyncIncrement();
16 | }
17 |
18 | private static void testSyncIncrement() {
19 | count = 0;
20 |
21 | ExecutorService executor = Executors.newFixedThreadPool(2);
22 |
23 | IntStream.range(0, NUM_INCREMENTS)
24 | .forEach(i -> executor.submit(Synchronized1::incrementSync));
25 |
26 | ConcurrentUtils.stop(executor);
27 |
28 | System.out.println(" Sync: " + count);
29 | }
30 |
31 | private static void testNonSyncIncrement() {
32 | count = 0;
33 |
34 | ExecutorService executor = Executors.newFixedThreadPool(2);
35 |
36 | IntStream.range(0, NUM_INCREMENTS)
37 | .forEach(i -> executor.submit(Synchronized1::increment));
38 |
39 | ConcurrentUtils.stop(executor);
40 |
41 | System.out.println("NonSync: " + count);
42 | }
43 |
44 | private static synchronized void incrementSync() {
45 | count = count + 1;
46 | }
47 |
48 | private static void increment() {
49 | count = count + 1;
50 | }
51 |
52 | }
--------------------------------------------------------------------------------
/java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Synchronized2.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.concurrent;
2 |
3 | import java.util.concurrent.ExecutorService;
4 | import java.util.concurrent.Executors;
5 | import java.util.stream.IntStream;
6 |
7 | public class Synchronized2 {
8 |
9 | private static final int NUM_INCREMENTS = 10000;
10 |
11 | private static int count = 0;
12 |
13 | public static void main(String[] args) {
14 | testSyncIncrement();
15 | }
16 |
17 | private static void testSyncIncrement() {
18 | count = 0;
19 |
20 | ExecutorService executor = Executors.newFixedThreadPool(2);
21 |
22 | IntStream.range(0, NUM_INCREMENTS)
23 | .forEach(i -> executor.submit(Synchronized2::incrementSync));
24 |
25 | ConcurrentUtils.stop(executor);
26 |
27 | System.out.println(count);
28 | }
29 |
30 | private static void incrementSync() {
31 | synchronized (Synchronized2.class) {
32 | count = count + 1;
33 | }
34 | }
35 |
36 | }
--------------------------------------------------------------------------------
/java8-concurrent/src/main/java/io/github/biezhi/java8/concurrent/Threads1.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.concurrent;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | public class Threads1 {
6 |
7 | public static void main(String[] args) {
8 | test1();
9 | // test2();
10 | // test3();
11 | }
12 |
13 | private static void test3() {
14 | Runnable runnable = () -> {
15 | try {
16 | System.out.println("Foo " + Thread.currentThread().getName());
17 | TimeUnit.SECONDS.sleep(1);
18 | System.out.println("Bar " + Thread.currentThread().getName());
19 | }
20 | catch (InterruptedException e) {
21 | e.printStackTrace();
22 | }
23 | };
24 |
25 | Thread thread = new Thread(runnable);
26 | thread.start();
27 | }
28 |
29 | private static void test2() {
30 | Runnable runnable = () -> {
31 | try {
32 | System.out.println("Foo " + Thread.currentThread().getName());
33 | Thread.sleep(1000);
34 | System.out.println("Bar " + Thread.currentThread().getName());
35 | }
36 | catch (InterruptedException e) {
37 | e.printStackTrace();
38 | }
39 | };
40 |
41 | Thread thread = new Thread(runnable);
42 | thread.start();
43 | }
44 |
45 | private static void test1() {
46 | Runnable runnable = () -> {
47 | String threadName = Thread.currentThread().getName();
48 | System.out.println("Hello " + threadName);
49 | };
50 |
51 | runnable.run();
52 |
53 | Thread thread = new Thread(runnable);
54 | thread.start();
55 |
56 | System.out.println("Done!");
57 | }
58 | }
--------------------------------------------------------------------------------
/java8-datetime-api/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | learn-java8
7 | io.github.biezhi
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | java8-datetime-api
13 |
14 |
15 |
--------------------------------------------------------------------------------
/java8-datetime-api/src/main/java/io/github/biezhi/datetime/ClockExample.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.datetime;
2 |
3 | import java.time.Clock;
4 | import java.time.Instant;
5 | import java.util.Date;
6 |
7 | /**
8 | * Clock 示例
9 | *
10 | * @author biezhi
11 | * @date 2018/3/3
12 | */
13 | public class ClockExample {
14 |
15 | public static void main(String[] args) {
16 | Clock clock = Clock.systemDefaultZone();
17 | long millis = clock.millis();
18 | Instant instant = clock.instant();
19 | Date legacyDate = Date.from(instant); // legacy java.util.Date
20 | System.out.println(millis);
21 | System.out.println(legacyDate);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/java8-datetime-api/src/main/java/io/github/biezhi/datetime/ConvertExample.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.datetime;
2 |
3 | import java.time.*;
4 | import java.util.Date;
5 |
6 | /**
7 | * 日期转换示例
8 | *
9 | * @author biezhi
10 | * @date 2018/3/3
11 | */
12 | public class ConvertExample {
13 |
14 | /**
15 | * LocalDate -> Date
16 | *
17 | * @param localDate
18 | * @return
19 | */
20 | public static Date toDate(LocalDate localDate) {
21 | ZoneId zone = ZoneId.systemDefault();
22 | Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
23 | return Date.from(instant);
24 | }
25 |
26 | /**
27 | * LocalDateTime -> Date
28 | *
29 | * @param localDateTime
30 | * @return
31 | */
32 | public static Date toDate(LocalDateTime localDateTime) {
33 | ZoneId zone = ZoneId.systemDefault();
34 | Instant instant = localDateTime.atZone(zone).toInstant();
35 | return Date.from(instant);
36 | }
37 |
38 | /**
39 | * LocalTime -> Date
40 | *
41 | * @param localTime
42 | * @return
43 | */
44 | public static Date toDate(LocalTime localTime) {
45 | LocalDate localDate = LocalDate.now();
46 | LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
47 | ZoneId zone = ZoneId.systemDefault();
48 | Instant instant = localDateTime.atZone(zone).toInstant();
49 | return Date.from(instant);
50 | }
51 |
52 | /**
53 | * Date -> LocalDate
54 | *
55 | * @param date
56 | * @return
57 | */
58 | public static LocalDate toLocalDate(Date date) {
59 | Instant instant = date.toInstant();
60 | ZoneId zone = ZoneId.systemDefault();
61 | LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
62 | return localDateTime.toLocalDate();
63 | }
64 |
65 | /**
66 | * Date -> LocalDateTime
67 | *
68 | * @param date
69 | * @return
70 | */
71 | public static LocalDateTime toLocalDateTime(Date date) {
72 | Instant instant = date.toInstant();
73 | ZoneId zone = ZoneId.systemDefault();
74 | return LocalDateTime.ofInstant(instant, zone);
75 | }
76 |
77 | /**
78 | * Date -> LocalTime
79 | *
80 | * @param date
81 | * @return
82 | */
83 | public static LocalTime toLocalTime(Date date) {
84 | Instant instant = date.toInstant();
85 | ZoneId zone = ZoneId.systemDefault();
86 | LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
87 | return localDateTime.toLocalTime();
88 | }
89 |
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/java8-datetime-api/src/main/java/io/github/biezhi/datetime/DateTimeFormatExample.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.datetime;
2 |
3 | import java.time.LocalDate;
4 | import java.time.LocalDateTime;
5 | import java.time.ZonedDateTime;
6 | import java.time.format.DateTimeFormatter;
7 | import java.util.Locale;
8 |
9 | /**
10 | * DateTimeFormatter 示例
11 | *
12 | * @author biezhi
13 | * @date 2018/3/2
14 | */
15 | public class DateTimeFormatExample {
16 |
17 | public static void main(String[] args) {
18 | DateTimeFormatter formatter = DateTimeFormatter.BASIC_ISO_DATE;
19 | String formattedDate = formatter.format(LocalDate.now());
20 | String formattedZonedDate = formatter.format(ZonedDateTime.now());
21 |
22 | System.out.println("LocalDate : " + formattedDate);
23 | System.out.println("formattedZonedDate : " + formattedZonedDate);
24 |
25 | LocalDateTime dateTime = LocalDateTime.now();
26 | String strDate1 = dateTime.format(DateTimeFormatter.BASIC_ISO_DATE); // 20180303
27 | String strDate2 = dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE); // 2013-03-03
28 | String strDate3 = dateTime.format(DateTimeFormatter.ISO_LOCAL_TIME); // 当前时间
29 | String strDate4 = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); // 2018-03-03
30 | // 今天是:2018年 三月 03日 星期六
31 | String strDate5 = dateTime.format(DateTimeFormatter.ofPattern("今天是:YYYY年 MMMM dd日 E", Locale.CHINESE));
32 |
33 | System.out.println(strDate1);
34 | System.out.println(strDate2);
35 | System.out.println(strDate3);
36 | System.out.println(strDate4);
37 | System.out.println(strDate5);
38 |
39 | // 将一个字符串解析成一个日期对象
40 | String strDate6 = "2018-03-03";
41 | String strDate7 = "2017-03-03 15:30:05";
42 |
43 | LocalDate date = LocalDate.parse(strDate6, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
44 | LocalDateTime dateTime1 = LocalDateTime.parse(strDate7, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
45 |
46 | System.out.println(date);
47 | System.out.println(dateTime1);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/java8-datetime-api/src/main/java/io/github/biezhi/datetime/DurationExample.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.datetime;
2 |
3 | import java.time.Duration;
4 | import java.time.Instant;
5 | import java.time.LocalDateTime;
6 |
7 | /**
8 | * Duration 示例
9 | *
10 | * @author biezhi
11 | * @date 2018/3/3
12 | */
13 | public class DurationExample {
14 |
15 | public static void main(String[] args) throws InterruptedException {
16 |
17 | // 创建Duration实例
18 | Instant first = Instant.now();
19 | Thread.sleep(3000);
20 | Instant second = Instant.now();
21 | Duration duration = Duration.between(first, second);
22 |
23 | // 访问Duration的时间
24 | long seconds = duration.getSeconds();
25 |
26 | System.out.println("相差 : " + seconds + " 秒");
27 |
28 | LocalDateTime from = LocalDateTime.now();
29 | LocalDateTime to = from.plusDays(5);
30 | Duration duration2 = Duration.between(from, to);
31 |
32 | System.out.println("从 from 到 to 相差 : " + duration2.toDays() + " 天");
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/java8-datetime-api/src/main/java/io/github/biezhi/datetime/InstantExample.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.datetime;
2 |
3 | import java.time.Instant;
4 |
5 | /**
6 | * Instant 示例
7 | *
8 | * @author biezhi
9 | * @date 2018/3/2
10 | */
11 | public class InstantExample {
12 |
13 | public static void main(String[] args) {
14 |
15 | // 创建一个Instant实例
16 | Instant now = Instant.now();
17 |
18 | // 访问Instant的时间
19 | long seconds = now.getEpochSecond();
20 | int nanos = now.getNano();
21 | System.out.println("seconds : " + seconds);
22 | System.out.println("nanos : " + nanos);
23 |
24 | // 3秒后
25 | Instant later = now.plusSeconds(3);
26 | // 3秒前
27 | Instant earlier = now.minusSeconds(3);
28 |
29 | System.out.println("current : " + now.toString());
30 | System.out.println("later : " + later);
31 | System.out.println("earlier : " + earlier);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/java8-datetime-api/src/main/java/io/github/biezhi/datetime/LocalDateExample.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.datetime;
2 |
3 | import java.time.DayOfWeek;
4 | import java.time.LocalDate;
5 | import java.time.Month;
6 |
7 | /**
8 | * LocalDate 示例
9 | *
10 | * @author biezhi
11 | * @date 2018/3/2
12 | */
13 | public class LocalDateExample {
14 |
15 | public static void main(String[] args) {
16 |
17 | // 创建一个LocalDate实例
18 | LocalDate localDate = LocalDate.now();
19 |
20 | // 使用年月日信息构造出LocalDate对象
21 | LocalDate localDate2 = LocalDate.of(2018, 3, 3);
22 |
23 | int year = localDate.getYear();
24 | Month month = localDate.getMonth();
25 | int dayOfMonth = localDate.getDayOfMonth();
26 | int dayOfYear = localDate.getDayOfYear();
27 | DayOfWeek dayOfWeek = localDate.getDayOfWeek();
28 |
29 | System.out.println("year : " + year);
30 | System.out.println("month : " + month.getValue());
31 | System.out.println("dayOfMonth : " + dayOfMonth);
32 | System.out.println("dayOfYear : " + dayOfYear);
33 | System.out.println("dayOfWeek : " + dayOfWeek.getValue());
34 |
35 | // 3年后
36 | LocalDate d1 = localDate2.plusYears(3);
37 | // 3年前
38 | LocalDate d2 = localDate2.minusYears(3);
39 | System.out.println("plusYears : " + d1);
40 | System.out.println("minusYears : " + d2);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/java8-datetime-api/src/main/java/io/github/biezhi/datetime/LocalDateTimeExample.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.datetime;
2 |
3 | import java.time.LocalDateTime;
4 |
5 | /**
6 | * LocalDateTime 示例
7 | *
8 | * @author biezhi
9 | * @date 2018/3/2
10 | */
11 | public class LocalDateTimeExample {
12 |
13 | public static void main(String[] args) {
14 |
15 | // 创建一个LocalDateTime实例
16 | LocalDateTime localDateTime = LocalDateTime.now();
17 |
18 | // 使用指定的年月日、时分秒、纳秒来新建对象
19 | LocalDateTime localDateTime2 = LocalDateTime.of(2018, 11, 26, 13, 55, 36, 123);
20 |
21 | // 3年后的现在
22 | LocalDateTime dt1 = localDateTime.plusYears(3);
23 | // 3年前的现在
24 | LocalDateTime dt2 = localDateTime.minusYears(3);
25 |
26 | System.out.println("localDateTime : " + localDateTime);
27 | System.out.println("localDateTime2 : " + localDateTime2);
28 | System.out.println("dt1 : " + dt1);
29 | System.out.println("dt2 : " + dt2);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/java8-datetime-api/src/main/java/io/github/biezhi/datetime/LocalTimeExample.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.datetime;
2 |
3 | import java.time.DayOfWeek;
4 | import java.time.LocalDate;
5 | import java.time.LocalTime;
6 | import java.time.Month;
7 |
8 | /**
9 | * LocalTime 示例
10 | *
11 | * @author biezhi
12 | * @date 2018/3/2
13 | */
14 | public class LocalTimeExample {
15 |
16 | public static void main(String[] args) {
17 |
18 | // 创建一个LocalTime实例
19 | LocalTime localTime = LocalTime.now();
20 |
21 | // 使用指定的时分秒和纳秒来新建对象
22 | LocalTime localTime2 = LocalTime.of(21, 30, 59, 11001);
23 |
24 | // 3小时后
25 | LocalTime localTimeLater = localTime.plusHours(3);
26 | // 3小时前
27 | LocalTime localTimeEarlier = localTime.minusHours(3);
28 |
29 | System.out.println("localTime : " + localTime);
30 | System.out.println("localTime2 : " + localTime2);
31 | System.out.println("localTimeLater : " + localTimeLater);
32 | System.out.println("localTimeEarlier: " + localTimeEarlier);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/java8-datetime-api/src/main/java/io/github/biezhi/datetime/ZoneIdExample.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.datetime;
2 |
3 | import java.time.ZoneId;
4 | import java.util.TimeZone;
5 |
6 | /**
7 | * ZoneId 示例
8 | *
9 | * @author biezhi
10 | * @date 2018/3/3
11 | */
12 | public class ZoneIdExample {
13 |
14 | public static void main(String[] args) {
15 |
16 | // 获取系统默认时区
17 | ZoneId defaultZoneId = ZoneId.systemDefault();
18 | ZoneId shanghaiZoneId = ZoneId.of("Asia/Shanghai");
19 |
20 | // TimeZone 转换为 ZoneId
21 | ZoneId oldToNewZoneId = TimeZone.getDefault().toZoneId();
22 |
23 | System.out.println(defaultZoneId);
24 | System.out.println(shanghaiZoneId);
25 | System.out.println(oldToNewZoneId);
26 |
27 | System.out.println(ZoneId.getAvailableZoneIds());
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/java8-datetime-api/src/main/java/io/github/biezhi/datetime/ZonedDateTimeExample.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.datetime;
2 |
3 | import java.time.Period;
4 | import java.time.ZoneId;
5 | import java.time.ZonedDateTime;
6 |
7 | /**
8 | * ZonedDateTime 示例
9 | *
10 | * @author biezhi
11 | * @date 2018/3/2
12 | */
13 | public class ZonedDateTimeExample {
14 |
15 | public static void main(String[] args) {
16 | // 创建一个ZonedDateTime实例
17 | ZonedDateTime dateTime = ZonedDateTime.now();
18 |
19 | // 使用指定的年月日、时分秒、纳秒以及时区ID来新建对象
20 | ZoneId zoneId = ZoneId.of("UTC+8");
21 | ZonedDateTime dateTime2 = ZonedDateTime.of(2018, 3, 8, 23, 45, 59, 1234, zoneId);
22 |
23 | // 3天后
24 | ZonedDateTime zoneDateTime = dateTime2.plus(Period.ofDays(3));
25 |
26 | ZoneId zoneId2 = ZoneId.of("Europe/Copenhagen");
27 | ZoneId zoneId3 = ZoneId.of("Europe/Paris");
28 |
29 | System.out.println("dateTime : " + dateTime);
30 | System.out.println("zoneDateTime : " + zoneDateTime);
31 | System.out.println("zoneId2 : " + zoneId2);
32 | System.out.println("zoneId3 : " + zoneId3);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/java8-default-methods/README.md:
--------------------------------------------------------------------------------
1 | # Java 8 默认方法和静态方法
2 |
3 |
--------------------------------------------------------------------------------
/java8-default-methods/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | learn-java8
7 | io.github.biezhi
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | java8-default-methods
13 |
14 |
15 |
--------------------------------------------------------------------------------
/java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/BasicCalculator.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.defaultmethods;
2 |
3 | public class BasicCalculator implements Calculator {
4 |
5 | @Override
6 | public int add(int first, int second) {
7 | return first + second;
8 | }
9 |
10 | @Override
11 | public int subtract(int first, int second) {
12 | return first - second;
13 | }
14 |
15 | @Override
16 | public int divide(int number, int divisor) {
17 | if (divisor == 0) {
18 | throw new IllegalArgumentException("divisor can't be zero.");
19 | }
20 | return number / divisor;
21 | }
22 |
23 | @Override
24 | public int multiply(int first, int second) {
25 | return first * second;
26 | }
27 | }
--------------------------------------------------------------------------------
/java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/Calculator.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.defaultmethods;
2 |
3 | /**
4 | * 计算器接口
5 | *
6 | * @author biezhi
7 | * @date 2018/2/11
8 | */
9 | public interface Calculator {
10 |
11 | int add(int first, int second);
12 |
13 | int subtract(int first, int second);
14 |
15 | int multiply(int first, int second);
16 |
17 | int divide(int number, int divisor);
18 |
19 | default int mod(int first, int second){
20 | return first % second;
21 | }
22 |
23 | static Calculator getInstance(){
24 | return new BasicCalculator();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/CalculatorFactory.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.defaultmethods;
2 |
3 | /**
4 | * @author biezhi
5 | * @date 2018/2/11
6 | */
7 | public class CalculatorFactory {
8 |
9 | public static Calculator getInstance(){
10 | return new BasicCalculator();
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/Collection.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.defaultmethods;
2 |
3 | import java.util.Iterator;
4 | import java.util.function.Predicate;
5 |
6 | /**
7 | * @author biezhi
8 | * @date 2018/2/11
9 | */
10 | public interface Collection extends java.util.Collection {
11 |
12 | default boolean removeIf2(Predicate predicate){
13 | boolean isRemoved = false;
14 | Iterator iterator = iterator();
15 | while(iterator.hasNext()){
16 | if(predicate.test(iterator.next())){
17 | iterator.remove();
18 | isRemoved = true;
19 | }
20 | }
21 | return isRemoved;
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/UseCalc.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.defaultmethods;
2 |
3 | /**
4 | * @author biezhi
5 | * @date 2018/2/11
6 | */
7 | public class UseCalc {
8 |
9 | public static void main(String[] args) {
10 |
11 | Calculator calculator = new BasicCalculator();
12 | int sum = calculator.add(1, 2);
13 | System.out.println(sum);
14 |
15 | Calculator cal = Calculator.getInstance();
16 | int difference = cal.subtract(3, 2);
17 | System.out.println(difference);
18 |
19 | System.out.println(cal.mod(3, 2));
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/conflict/A.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.defaultmethods.conflict;
2 |
3 | /**
4 | * @author biezhi
5 | * @date 2018/2/11
6 | */
7 | public interface A {
8 |
9 | default void sayHello(){
10 | System.out.println("你好,我是 Java 8");
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/conflict/App.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.defaultmethods.conflict;
2 |
3 | /**
4 | * @author biezhi
5 | * @date 2018/2/11
6 | */
7 | public class App implements A {
8 |
9 | @Override
10 | public void sayHello(){
11 | System.out.println("你好,我是 APP");
12 | }
13 |
14 | public static void main(String[] args) {
15 | new App().sayHello();
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/conflict/App2.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.defaultmethods.conflict;
2 |
3 | /**
4 | * @author biezhi
5 | * @date 2018/2/11
6 | */
7 | public class App2 implements A, B, C {
8 |
9 | public static void main(String[] args) {
10 | new App2().sayHello();
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/conflict/App3.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.defaultmethods.conflict;
2 |
3 | /**
4 | * @author biezhi
5 | * @date 2018/2/11
6 | */
7 | public class App3 implements A, B {
8 |
9 | @Override
10 | public void sayHello() {
11 | System.out.println("大家好,我系古天乐。探晚懒月,里没有晚过的传奇。" +
12 | "点一下,晚一连,撞贝不花一份钱。机要晚过了传骑,里就系我的凶第。");
13 | }
14 |
15 | public static void main(String[] args) {
16 | new App3().sayHello();
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/conflict/B.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.defaultmethods.conflict;
2 |
3 | /**
4 | * @author biezhi
5 | * @date 2018/2/11
6 | */
7 | public interface B {
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/java8-default-methods/src/main/java/io/github/biezhi/java8/defaultmethods/conflict/C.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.defaultmethods.conflict;
2 |
3 | /**
4 | * @author biezhi
5 | * @date 2018/2/11
6 | */
7 | public interface C extends A {
8 |
9 | default void sayHello(){
10 | System.out.println("你好,我是 渣渣辉");
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/java8-growing/README.md:
--------------------------------------------------------------------------------
1 | # Java 8 的发展
2 |
3 | ## JDK 5
4 |
5 | **自动装箱与拆箱**
6 |
7 | JDK1.5为每一个基本数据类型定义了一个封装类。使java中的基本数据类型也有自己的对象
8 |
9 | ```bash
10 | int -->Integer
11 | double --> Double
12 | long --> Long
13 | char --> Character
14 | float --> Float
15 | boolean --> Boolean
16 | short --> Short
17 | byte -- > Byte
18 | ```
19 |
20 | - 自动装包:将基本类型转换成为对象,例如:`int --> Integer`
21 | - 自动拆包:将对象转换成为基本数据类型,例如:`Integer --> int`
22 |
23 | 对于 JDK1.5 之前集合总不能存放基本数据类型的问题,现在也能够解决。
24 |
25 | **枚举**
26 |
27 | 枚举是 JDK1.5 推出的一个比较重要的特性。其关键字为 `enum`
28 | 例如:定义代表交通灯的枚举
29 |
30 | ```java
31 | public enum MyEnum{
32 | RED,GREEN,YELLOW
33 | }
34 | ```
35 |
36 | **静态导入**
37 |
38 | - 优点:使用静态导入可以使被导入类的所有静态变量和静态方法在当前类直接可见,使用这些静态成员无需再给出他们的类名。
39 | - 缺点:过度使用会降低代码的可读性
40 |
41 | **变长参数**
42 |
43 | 在JDK1.5以前,当我们要为一个方法传递多个类型相同的参数时,
44 | 我们有两种方法解决
45 |
46 | 1. 直接传递一个数组过去
47 | 2. 有多少个参数就传递多少个参数。
48 |
49 | 例如:
50 |
51 | ```java
52 | public void printColor(String red,String green,String yellow){
53 | }
54 | ```
55 |
56 | 或者
57 |
58 | ```java
59 | public void printColor(String[] colors){
60 |
61 | }
62 | ```
63 |
64 | 这样编写方法参数虽然能够实现我们想要的效果,但是,这样是不是有点麻烦呢?
65 | 再者,如果参数个数不确定,我们怎么办呢?Java JDK1.5为我们提供的可变参数就能够完美的解决这个问题.
66 |
67 | 例如:
68 |
69 | ```java
70 | public void printColor(String... colors){
71 |
72 | }
73 | ```
74 |
75 | 如果参数的类型相同,那么可以使用 `类型+三个点` ,后面跟一个参数名称的形式。
76 | 这样的好处就是,只要参数类型相同,无论传递几个参数都没有限制
77 | 注意:可变参数必须是参数列表的最后一项(该特性对对象和基本数据类型都适用)
78 |
79 | **泛型**
80 |
81 | ```java
82 | //给集合指定存入类型,上面这个集合在存入数据的时候必须存入String类型的数据,否则编译器会报错
83 | List strs = new ArrayList();
84 | ```
85 |
86 | “泛型” 意味着编写的代码可以被不同类型的对象所重用。
87 | 可见泛型的提出是为了编写重用性更好的代码。
88 | 泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
89 |
90 | 比如常见的集合类 `LinkedList`,其实现的接口名后有个特殊的部分 `<>`,而且它的成员的类型 Link 也包含一个 `<>`,这个符号的就是类型参数,
91 | 它使得在运行中,创建一个 LinkedList 时可以传入不同的类型,比如 `new LinkedList`,这样它的成员存放的类型也是 `String`。
92 |
93 | **For-Each循环**
94 |
95 | 例如上面这个集合我们可以通过for-each遍历,这样更加简单清晰
96 |
97 | ```java
98 | for(String s : strs){
99 | System.out.println(s);
100 | }
101 | ```
102 |
103 | > 注意:使用for-each遍历集合时,要遍历的集合必须实现了Iterator接口
104 |
105 | **线程并发库**
106 |
107 | 线程并发库是 Java1.5 提出的关于多线程处理的高级功能,所在包:`java.util.concurrent` 包括
108 |
109 | 1. 线程互斥工具类:Lock,ReadWriteLock
110 | 2. 线程通信:Condition
111 | 3. 线程池:ExecutorService
112 | 3. 同步队列:ArrayBlockingQueue
113 | 4. 同步集合:ConcurrentHashMap,CopyOnWriteArrayList
114 | 5. 线程同步工具:Semaphore
115 |
116 | ## JDK 6
117 |
118 | **Desktop类和SystemTray类**
119 |
120 | 前者可以用来打开系统默认浏览器浏览指定的URL,打开系统默认邮件客户端给指定的邮箱发邮件,
121 | 用默认应用程序打开或编辑文件(比如,用记事本打开以 txt 为后缀名的文件),
122 | 用系统默认的打印机打印文档;后者可以用来在系统托盘区创建一个托盘程序。
123 |
124 | **使用Compiler API**
125 |
126 | 现在我们可以用JDK1.6 的Compiler API(JSR 199)去动态编译Java源文件,
127 | Compiler API结合反射功能就可以实现动态的产生Java代码并编译执行这些代码,有点动态语言的特征。
128 |
129 | 这个特性对于某些需要用到动态编译的应用程序相当有用,比如JSP Web Server,当我们手动修改JSP后,
130 | 是不希望需要重启Web Server才可以看到效果的,这时候我们就可以用Compiler API来实现动态编译JSP文件。
131 | 当然,现在的JSP Web Server也是支持JSP热部署的,现在的JSP Web Server通过在运行期间通过Runtime.exec或ProcessBuilder来调用javac来编译代码,
132 | 这种方式需要我们产生另一个进程去做编译工作,不够优雅而且容易使代码依赖与特定的操作系统;
133 | Compiler API通过一套易用的标准的API提供了更加丰富的方式去做动态编译,而且是跨平台的。
134 |
135 | **轻量级Http Server API**
136 |
137 | JDK1.6 提供了一个简单的 Http Server API,据此我们可以构建自己的嵌入式 Http Server,
138 | 它支持Http和Https协议,提供了HTTP1.1的部分实现,没有被实现的那部分可以通过扩展已有的 Http Server API来实现,
139 | 程序员必须自己实现 HttpHandler 接口,HttpServer 会调用 `HttpHandler` 实现类的回调方法来处理客户端请求,
140 | 在这里,我们把一个 Http 请求和它的响应称为一个交换,包装成 `HttpExchange` 类,`HttpServer` 负责将 `HttpExchange` 传给 `HttpHandler` 实现类的回调方法。
141 |
142 | **用Console开发控制台程序**
143 |
144 | JDK1.6 中提供了 `java.io.Console` 类专用来访问基于字符的控制台设备。
145 | 你的程序如果要与 Windows 下的 cmd 或者 Linux 下的 Terminal 交互,就可以用 `Console` 类代劳。
146 | 但我们不总是能得到可用的 Console,一个JVM是否有可用的 Console 依赖于底层平台和 JVM 如何被调用。
147 | 如果JVM是在交互式命令行(比如 Windows 的 cmd)中启动的,并且输入输出没有重定向到另外的地方,那么就可以得到一个可用的 Console 实例。
148 |
149 | **对脚本语言的支持**
150 |
151 | 如:ruby,groovy,javascript。
152 |
153 | ## JDK 7
154 |
155 | **数字变量对下滑线的支持**
156 |
157 | JDK1.7可以在数值类型的变量里添加下滑线,但是有几个地方是不能添加的
158 |
159 | 1. 数字的开头和结尾
160 | 2. 小数点前后
161 | 3. F或者L前
162 |
163 | 例如:
164 |
165 | ```java
166 | int num = 1234_5678_9;
167 | float num2 = 222_33F;
168 | long num3 = 123_000_111L;
169 | ```
170 |
171 | **switch对String的支持**
172 |
173 | ```java
174 | String status = "orderState";
175 | switch (status) {
176 | case "ordercancel":
177 | System.out.println("订单取消");
178 | break;
179 | case "orderSuccess":
180 | System.out.println("预订成功");
181 | break;
182 | default:
183 | System.out.println("状态未知");
184 | }
185 | ```
186 |
187 | **try-with-resource**
188 |
189 | - `try-with-resources` 是一个定义了一个或多个资源的 try 声明,这个资源是指程序处理完它之后需要关闭它的对象。
190 | - `try-with-resources` 确保每一个资源在处理完成后都会被关闭。
191 |
192 | 可以使用try-with-resources的资源有: 任何实现了 `java.lang.AutoCloseable` 接口 `java.io.Closeable` 接口的对象。
193 |
194 | 例如:
195 |
196 | ```java
197 | public static String readFirstLineFromFile(String path) throws IOException {
198 |
199 | try (BufferedReader br = new BufferedReader(new FileReader(path))) {
200 | return br.readLine();
201 | }
202 | }
203 | ```
204 |
205 | 在 java 7 以及以后的版本里,`BufferedReader` 实现了 `java.lang.AutoCloseable` 接口。
206 | 由于 `BufferedReader` 定义在 `try-with-resources` 声明里,无论 `try` 语句正常还是异常的结束,
207 | 它都会自动的关掉。而在 java7 以前,你需要使用 `finally` 块来关掉这个对象。
208 |
209 | **捕获多种异常并用改进后的类型检查来重新抛出异常**
210 |
211 | ```java
212 | public static void first(){
213 | try {
214 | BufferedReader reader = new BufferedReader(new FileReader(""));
215 | Connection con = null;
216 | Statement stmt = con.createStatement();
217 | } catch (IOException | SQLException e) {
218 | //捕获多个异常,e就是final类型的
219 | e.printStackTrace();
220 | }
221 | }
222 | ```
223 |
224 | 优点:用一个 `catch` 处理多个异常,比用多个 `catch` 每个处理一个异常生成的字节码要更小更高效。
225 |
226 | **创建泛型时类型推断**
227 |
228 | 只要编译器可以从上下文中推断出类型参数,你就可以用一对空着的尖括号 `<>` 来代替泛型参数。
229 | 这对括号私下被称为菱形(diamond)。 在Java SE 7之前,你声明泛型对象时要这样
230 |
231 | ```java
232 | List list = new ArrayList();
233 | ```
234 |
235 | 而在Java SE7以后,你可以这样
236 |
237 | ```java
238 | List list = new ArrayList<>();
239 | ```
240 |
241 | 因为编译器可以从前面(List)推断出推断出类型参数,所以后面的 `ArrayList` 之后可以不用写泛型参数了,只用一对空着的尖括号就行。
242 | 当然,你必须带着菱形 `<>`,否则会有警告的。
243 | Java SE7 只支持有限的类型推断:只有构造器的参数化类型在上下文中被显著的声明了,你才可以使用类型推断,否则不行。
244 |
245 | ```java
246 | List list = new ArrayList<>();l
247 | list.add("A");
248 | //这个不行
249 | list.addAll(new ArrayList<>());
250 | // 这个可以
251 | List extends String> list2 = new ArrayList<>();
252 | list.addAll(list2);
253 | ```
254 |
255 | ## JDK 8
256 |
257 | **Lambda表达式和函数式接口**
258 |
259 | Lambda表达式(也称为闭包)是Java 8中最大和最令人期待的语言改变。它允许我们将函数当成参数传递给某个方法,
260 | 或者把代码本身当作数据处理:函数式开发者非常熟悉这些概念。很多JVM平台上的语言(Groovy、Scala等)从诞生之日就支持Lambda表达式,但是Java开发者没有选择,只能使用匿名内部类代替Lambda表达式。
261 | Lambda的设计耗费了很多时间和很大的社区力量,最终找到一种折中的实现方案,可以实现简洁而紧凑的语言结构。最简单的Lambda表达式可由逗号分隔的参数列表、->符号和语句块组成。
262 |
263 | Lambda的设计者们为了让现有的功能与Lambda表达式良好兼容,考虑了很多方法,于是产生了函数接口这个概念。函数接口指的是只有一个函数的接口,这样的接口可以隐式转换为Lambda表达式。java.lang.Runnable和java.util.concurrent.Callable是函数式接口的最佳例子。在实践中,函数式接口非常脆弱:只要某个开发者在该接口中添加一个函数,则该接口就不再是函数式接口进而导致编译失败。为了克服这种代码层面的脆弱性,并显式说明某个接口是函数式接口,Java 8 提供了一个特殊的注解@FunctionalInterface(Java 库中的所有相关接口都已经带有这个注解了),举个简单的函数式接口的定义
264 |
265 | **接口的默认方法和静态方法**
266 |
267 | Java 8使用两个新概念扩展了接口的含义:默认方法和静态方法。默认方法使得接口有点类似traits,不过要实现的目标不一样。默认方法使得开发者可以在 不破坏二进制兼容性的前提下,往现存接口中添加新的方法,即不强制那些实现了该接口的类也同时实现这个新加的方法。
268 | 默认方法和抽象方法之间的区别在于抽象方法需要实现,而默认方法不需要。接口提供的默认方法会被接口的实现类继承或者覆写
269 | 由于JVM上的默认方法的实现在字节码层面提供了支持,因此效率非常高。默认方法允许在不打破现有继承体系的基础上改进接口。该特性在官方库中的应用是:给java.util.Collection接口添加新方法,如stream()、parallelStream()、forEach()和removeIf()等等。
270 | 尽管默认方法有这么多好处,但在实际开发中应该谨慎使用:在复杂的继承体系中,默认方法可能引起歧义和编译错误。如果你想了解更多细节,可以参考官方文档。
271 |
272 | **更好的类型推断**
273 |
274 | Java 8 编译器在类型推断方面有很大的提升,在很多场景下编译器可以推导出某个参数的数据类型,从而使得代码更为简洁。
275 |
276 | 参数 `Value.defaultValue()` 的类型由编译器推导得出,不需要显式指明。在Java 7中这段代码会有编译错误,除非使用 `Value.defaultValue()`。
277 |
278 | **Optional**
279 |
280 | Java应用中最常见的bug就是空值异常。在Java 8之前,Google Guava引入了 `Optionals` 类来解决 `NullPointerException`,
281 | 从而避免源码被各种 `null` 检查污染,以便开发者写出更加整洁的代码。Java 8也将Optional加入了官方库。
282 | `Optional` 仅仅是一个容易存放T类型的值或者null。它提供了一些有用的接口来避免显式的null检查,可以参考Java 8官方文档了解更多细节。
283 |
284 | 如果Optional实例持有一个非空值,则 `isPresent()` 方法返回true,否则返回false;`orElseGet()` 方法,Optional实例持有null,
285 | 则可以接受一个lambda表达式生成的默认值;map()方法可以将现有的 `Optional` 实例的值转换成新的值;orElse()方法与orElseGet()方法类似,
286 | 但是在持有null的时候返回传入的默认值。
287 |
288 | **Streams**
289 |
290 | 新增的Stream API(java.util.stream)将生成环境的函数式编程引入了Java库中。
291 | 这是目前为止最大的一次对Java库的完善,以便开发者能够写出更加有效、更加简洁和紧凑的代码。
292 |
293 | Task 类有一个分数(或伪复杂度)的概念,另外还有两种状态:OPEN 或者 CLOSED。现在假设有一个task集合,
294 | 首先看一个问题:在这个task集合中一共有多少个OPEN状态的点?在Java 8之前,要解决这个问题,则需要使用foreach循环遍历task集合;
295 | 但是在Java 8中可以利用steams解决:包括一系列元素的列表,并且支持顺序和并行处理。
296 |
297 | ```java
298 | final Collection tasks = Arrays.asList(
299 | new Task(Status.OPEN, 5),
300 | new Task(Status.OPEN, 13),
301 | new Task(Status.CLOSED, 8)
302 | );
303 |
304 | // Calculate total points of all active tasks using sum()
305 | final long totalPointsOfOpenTasks = tasks
306 | .stream()
307 | .filter(task -> task.getStatus() == Status.OPEN)
308 | .mapToInt(Task::getPoints)
309 | .sum();
310 |
311 | System.out.println("Total points: " + totalPointsOfOpenTasks);
312 | ```
313 |
314 | 这里有很多知识点值得说。首先,tasks集合被转换成steam表示;其次,在steam上的filter操作会过滤掉所有CLOSED的task;
315 | 第三,mapToInt操作基于每个task实例的Task::getPoints方法将task流转换成Integer集合;最后,通过sum方法计算总和,得出最后的结果。
316 |
317 | **新的日期时间 API**
318 |
319 | Java 8引入了新的Date-Time API(JSR 310)来改进时间、日期的处理。时间和日期的管理一直是最令Java开发者痛苦的问题。
320 | java.util.Date 和后来的 java.util.Calendar 一直没有解决这个问题(甚至令开发者更加迷茫)。
321 |
322 | 因为上面这些原因,诞生了第三方库Joda-Time,可以替代Java的时间管理API。
323 | Java 8中新的时间和日期管理API深受Joda-Time影响,并吸收了很多Joda-Time的精华。
324 | 新的java.time包包含了所有关于日期、时间、时区、Instant(跟日期类似但是精确到纳秒)、duration(持续时间)和时钟操作的类。
325 | 新设计的API认真考虑了这些类的不变性(从java.util.Calendar吸取的教训),如果某个实例需要修改,则返回一个新的对象。
326 |
327 | 第二,关注下LocalDate和LocalTime类。LocalDate仅仅包含ISO-8601日历系统中的日期部分;LocalTime则仅仅包含该日历系统中的时间部分。这两个类的对象都可以使用Clock对象构建得到。
328 | LocalDateTime类包含了LocalDate和LocalTime的信息,但是不包含ISO-8601日历系统中的时区信息。这里有一些关于LocalDate和LocalTime的例子:
329 | 如果你需要特定时区的data/time信息,则可以使用ZoneDateTime,它保存有ISO-8601日期系统的日期和时间,而且有时区信息。
330 |
331 | **Nashorn JavaScript引擎**
332 |
333 | Java 8提供了新的Nashorn JavaScript引擎,使得我们可以在JVM上开发和运行JS应用。
334 | Nashorn JavaScript引擎是javax.script.ScriptEngine的另一个实现版本,这类Script引擎遵循相同的规则,允许Java和JavaScript交互使用,例子代码如下:
335 |
336 | **Base64**
337 |
338 | 对 Base64 编码的支持已经被加入到Java 8官方库中,这样不需要使用第三方库就可以进行Base64编码,例子代码如下:
339 |
340 | ```java
341 | final String text = "Lets Learn Java 8!";
342 |
343 | final String encoded = Base64
344 | .getEncoder()
345 | .encodeToString(text.getBytes(StandardCharsets.UTF_8));
346 | System.out.println(encoded);
347 |
348 | final String decoded = new String(
349 | Base64.getDecoder().decode(encoded),
350 | StandardCharsets.UTF_8);
351 | System.out.println(decoded);
352 | ```
353 |
354 | 新的Base64API也支持URL和MINE的编码解码。
355 |
--------------------------------------------------------------------------------
/java8-growing/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | learn-java8
7 | io.github.biezhi
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | java8-growing
13 |
14 |
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk5/AutoBoxing.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk5;
2 |
3 | /**
4 | * 自动装箱、拆箱
5 | *
6 | * @author biezhi
7 | * @date 2018/2/8
8 | */
9 | public class AutoBoxing {
10 |
11 | public static void main(String[] args) {
12 | int a = new Integer(66);
13 | Integer b = 18;
14 |
15 | Boolean flag = true;
16 | boolean isBug = Boolean.FALSE;
17 |
18 | }
19 |
20 | }
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk5/Concurrent.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk5;
2 |
3 | import java.util.List;
4 | import java.util.Map;
5 | import java.util.Queue;
6 | import java.util.concurrent.*;
7 | import java.util.concurrent.locks.Condition;
8 | import java.util.concurrent.locks.Lock;
9 | import java.util.concurrent.locks.ReentrantLock;
10 |
11 | /**
12 | * 并发库
13 | *
14 | * @author biezhi
15 | * @date 2018/2/8
16 | */
17 | public class Concurrent {
18 |
19 | public void lock() {
20 | Lock lock = new ReentrantLock();
21 | lock.lock();
22 | try {
23 | System.out.println("hello world");
24 | } finally {
25 | lock.unlock();
26 | }
27 | }
28 |
29 | public void condition() throws InterruptedException {
30 | Lock lock = new ReentrantLock();
31 | Condition condition = lock.newCondition();
32 | // do something
33 | condition.await(10, TimeUnit.SECONDS);
34 | System.out.println("Get result.");
35 | }
36 |
37 | public void executorService() {
38 | ExecutorService executorService = Executors.newFixedThreadPool(3);
39 | executorService.submit(new Runnable() {
40 | @Override
41 | public void run() {
42 | System.out.println("Task is running.");
43 | }
44 | });
45 | }
46 |
47 | public void blockingDeque() {
48 | Queue blockingDeque = new ArrayBlockingQueue<>(20);
49 | blockingDeque.add(1);
50 | blockingDeque.add(2);
51 | blockingDeque.add(3);
52 |
53 | blockingDeque.peek();
54 | }
55 |
56 | public void concurrentHashMap() {
57 | Map concurrentHashMap = new ConcurrentHashMap<>();
58 | concurrentHashMap.put("Hello", 1);
59 | concurrentHashMap.put("World", 2);
60 |
61 | System.out.println(concurrentHashMap.get("Hello"));
62 | }
63 |
64 | public void copyOnWriteList() {
65 | List copyOnWriteList = new CopyOnWriteArrayList<>();
66 | copyOnWriteList.add("a");
67 | copyOnWriteList.add("b");
68 | copyOnWriteList.add("c");
69 |
70 | System.out.println(copyOnWriteList.size());
71 | }
72 |
73 | public void semaphore() {
74 | Semaphore semaphore = new Semaphore(3);
75 | try {
76 | semaphore.acquire();
77 | System.out.println(Thread.currentThread().getName() + " is working");
78 | Thread.sleep(1000);
79 | semaphore.release();
80 | System.out.println(Thread.currentThread().getName() + " is over");
81 | } catch (InterruptedException e) {
82 | }
83 | }
84 |
85 | }
86 |
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk5/EnumDemo.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk5;
2 |
3 | /**
4 | * 枚举
5 | *
6 | * @author biezhi
7 | * @date 2018/2/8
8 | */
9 | public enum EnumDemo {
10 |
11 | RED, GREEN, YELLOW
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk5/ForEach.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk5;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 |
6 | /**
7 | * for each
8 | *
9 | * @author biezhi
10 | * @date 2018/2/8
11 | */
12 | public class ForEach {
13 |
14 | public static void main(String[] args) {
15 |
16 | int[] arr = {1, 4, 5, 7};
17 |
18 | for (int i : arr) {
19 | System.out.println(i);
20 | }
21 |
22 | List names = Arrays.asList("王爵nice", "Gay冰", "A*熊");
23 | for (String name : names) {
24 | System.out.println(name);
25 | }
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk5/Generic.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk5;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | /**
7 | * 泛型
8 | *
9 | * @author biezhi
10 | * @date 2018/2/8
11 | */
12 | public class Generic {
13 |
14 | public T getById(Integer id){
15 | return null;
16 | }
17 |
18 | public static void main(String[] args) {
19 |
20 | Map map = new HashMap<>();
21 |
22 | Generic generic = new Generic<>();
23 |
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk5/StaticImport.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk5;
2 |
3 | import static java.lang.System.out;
4 |
5 | /**
6 | * 静态导入
7 | *
8 | * @author biezhi
9 | * @date 2018/2/8
10 | */
11 | public class StaticImport {
12 |
13 | public static void main(String[] args) {
14 | out.println("Hi let learn java 8.");
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk5/VarArgs.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk5;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 |
6 | /**
7 | * 变长参数
8 | *
9 | * @author biezhi
10 | * @date 2018/2/8
11 | */
12 | public class VarArgs {
13 |
14 | public static List asList(String[] names){
15 | return Arrays.asList(names);
16 | }
17 |
18 | public static void main(String[] args) {
19 | List hello = Arrays.asList("王爵nice", "Gay冰", "A*熊");
20 |
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk6/CompilerAPI.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk6;
2 |
3 | import javax.tools.*;
4 | import java.io.ByteArrayOutputStream;
5 | import java.io.IOException;
6 | import java.io.OutputStream;
7 | import java.lang.reflect.Method;
8 | import java.net.URI;
9 | import java.util.ArrayList;
10 | import java.util.Arrays;
11 | import java.util.Iterator;
12 | import java.util.List;
13 |
14 | /**
15 | * 使用Compiler API
16 | *
17 | * @author biezhi
18 | * @date 2018/2/8
19 | */
20 | public class CompilerAPI {
21 |
22 | public static void main(String[] args) throws Exception {
23 | String program = "" +
24 | "public class LearnJava6 {\n" +
25 | " public static void main(String[] args) {\n" +
26 | " System.out.println(\"欢迎你学习跟上 Java 8 之 CompilerAPI!\");\n" +
27 | " }\n" +
28 | "}\n";
29 |
30 | JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
31 |
32 | JavaFileObject compilationUnit =
33 | new StringJavaFileObject("LearnJava6", program);
34 |
35 | SimpleJavaFileManager fileManager =
36 | new SimpleJavaFileManager(compiler.getStandardFileManager(null, null, null));
37 |
38 | JavaCompiler.CompilationTask compilationTask = compiler.getTask(
39 | null, fileManager, null, null, null, Arrays.asList(compilationUnit));
40 |
41 | compilationTask.call();
42 |
43 | CompiledClassLoader classLoader =
44 | new CompiledClassLoader(fileManager.getGeneratedOutputFiles());
45 |
46 | Class> codeGenTest = classLoader.loadClass("LearnJava6");
47 | Method main = codeGenTest.getMethod("main", String[].class);
48 | main.invoke(null, new Object[]{null});
49 | }
50 |
51 | private static class StringJavaFileObject extends SimpleJavaFileObject {
52 | private final String code;
53 |
54 | public StringJavaFileObject(String name, String code) {
55 | super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension),
56 | Kind.SOURCE);
57 | this.code = code;
58 | }
59 |
60 | @Override
61 | public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
62 | return code;
63 | }
64 | }
65 |
66 | private static class ClassJavaFileObject extends SimpleJavaFileObject {
67 | private final ByteArrayOutputStream outputStream;
68 | private final String className;
69 |
70 | protected ClassJavaFileObject(String className, Kind kind) {
71 | super(URI.create("mem:///" + className.replace('.', '/') + kind.extension), kind);
72 | this.className = className;
73 | outputStream = new ByteArrayOutputStream();
74 | }
75 |
76 | @Override
77 | public OutputStream openOutputStream() throws IOException {
78 | return outputStream;
79 | }
80 |
81 | public byte[] getBytes() {
82 | return outputStream.toByteArray();
83 | }
84 |
85 | public String getClassName() {
86 | return className;
87 | }
88 | }
89 |
90 | private static class SimpleJavaFileManager extends ForwardingJavaFileManager {
91 | private final List outputFiles;
92 |
93 | protected SimpleJavaFileManager(JavaFileManager fileManager) {
94 | super(fileManager);
95 | outputFiles = new ArrayList();
96 | }
97 |
98 | @Override
99 | public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling) throws IOException {
100 | ClassJavaFileObject file = new ClassJavaFileObject(className, kind);
101 | outputFiles.add(file);
102 | return file;
103 | }
104 |
105 | public List getGeneratedOutputFiles() {
106 | return outputFiles;
107 | }
108 | }
109 |
110 | private static class CompiledClassLoader extends ClassLoader {
111 | private final List files;
112 |
113 | private CompiledClassLoader(List files) {
114 | this.files = files;
115 | }
116 |
117 | @Override
118 | protected Class> findClass(String name) throws ClassNotFoundException {
119 | Iterator itr = files.iterator();
120 | while (itr.hasNext()) {
121 | ClassJavaFileObject file = itr.next();
122 | if (file.getClassName().equals(name)) {
123 | itr.remove();
124 | byte[] bytes = file.getBytes();
125 | return super.defineClass(name, bytes, 0, bytes.length);
126 | }
127 | }
128 | return super.findClass(name);
129 | }
130 | }
131 | }
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk6/Console.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk6;
2 |
3 | /**
4 | * 用Console开发控制台程序
5 | *
6 | * @author biezhi
7 | * @date 2018/2/8
8 | */
9 | public class Console {
10 |
11 | public static void main(String[] args) {
12 |
13 | java.io.Console console = System.console();
14 |
15 | if (console != null) {
16 | String user = new String(console.readLine(" Enter User: ", new Object[0]));
17 | String pwd = new String(console.readPassword(" Enter Password: ", new Object[0]));
18 | console.printf(" User name is:%s ", new Object[]{user});
19 | console.printf(" Password is:%s ", new Object[]{pwd});
20 | } else {
21 | System.out.println(" No Console! ");
22 | }
23 |
24 | }
25 | }
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk6/DesktopTray.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk6;
2 |
3 | /**
4 | * Desktop类和SystemTray类
5 | *
6 | * https://www.programcreek.com/java-api-examples/java.awt.Desktop
7 | *
8 | * @author biezhi
9 | * @date 2018/2/8
10 | */
11 | public class DesktopTray {
12 |
13 | }
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk6/HttpServerAPI.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk6;
2 |
3 | import com.sun.net.httpserver.HttpExchange;
4 | import com.sun.net.httpserver.HttpHandler;
5 | import com.sun.net.httpserver.HttpServer;
6 |
7 | import java.io.IOException;
8 | import java.io.InputStream;
9 | import java.io.OutputStream;
10 | import java.net.InetSocketAddress;
11 |
12 | /**
13 | * Http Server
14 | *
15 | * @author biezhi
16 | * @date 2018/2/8
17 | */
18 | public class HttpServerAPI {
19 |
20 | private static int count = 0;
21 |
22 | static class MyHandler implements HttpHandler {
23 | @Override
24 | public void handle(HttpExchange he) throws IOException {
25 | System.out.println("Request " + count++);
26 | System.out.println(he.getHttpContext().getPath());
27 |
28 | InputStream is = he.getRequestBody();
29 | String response = "Lets Learn Java8.";
30 | he.sendResponseHeaders(200, response.length());
31 | OutputStream os = he.getResponseBody();
32 | os.write(response.getBytes());
33 | os.close();
34 | }
35 | }
36 |
37 | public static void main(String[] args) {
38 | try {
39 | HttpServer hs = HttpServer.create(new InetSocketAddress(8080), 0);
40 | hs.createContext("/", new MyHandler());
41 | hs.createContext("/java", new MyHandler());
42 | hs.setExecutor(null);
43 | hs.start();
44 | System.out.println("---begin---");
45 | System.out.println("Listening on " + hs.getAddress());
46 | } catch (IOException ioe) {
47 | ioe.printStackTrace();
48 | }
49 | }
50 |
51 | }
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk6/ScriptEngineDemo.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk6;
2 |
3 | import javax.script.Invocable;
4 | import javax.script.ScriptEngine;
5 | import javax.script.ScriptEngineManager;
6 | import java.io.FileReader;
7 |
8 | /**
9 | * 对脚本语言的支持
10 | *
11 | * @author biezhi
12 | * @date 2018/2/8
13 | */
14 | public class ScriptEngineDemo {
15 |
16 | public static void main(String[] args) {
17 |
18 | ScriptEngineManager manager = new ScriptEngineManager();
19 | ScriptEngine engine = manager.getEngineByName("ECMAScript");
20 | try {
21 | String jsPath = ScriptEngineDemo.class.getResource("/test.js").getPath();
22 |
23 | engine.eval(new FileReader(jsPath));
24 |
25 | Invocable invokableEngine = (Invocable) engine;
26 |
27 | Object ret = invokableEngine.invokeFunction("test", null);
28 |
29 | System.out.println("The result is : " + ret);
30 | } catch (Exception e) {
31 | e.printStackTrace();
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk7/CatchMultiException.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk7;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.FileReader;
5 | import java.io.IOException;
6 | import java.sql.Connection;
7 | import java.sql.SQLException;
8 | import java.sql.Statement;
9 |
10 | /**
11 | * 捕获多异常
12 | *
13 | * @author biezhi
14 | * @date 2018/2/8
15 | */
16 | public class CatchMultiException {
17 |
18 | public static void main(String[] args) {
19 | try {
20 | BufferedReader reader = new BufferedReader(new FileReader(""));
21 | Connection con = null;
22 | Statement stmt = con.createStatement();
23 | } catch (IOException | SQLException e) {
24 | //捕获多个异常,e就是final类型的
25 | e.printStackTrace();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk7/NumericUnderline.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk7;
2 |
3 | /**
4 | * 数字下划线支持
5 | *
6 | * @author biezhi
7 | * @date 2018/2/8
8 | */
9 | public class NumericUnderline {
10 |
11 | public static void main(String[] args) {
12 | int num = 1234_5678_9;
13 | float num2 = 222_33F;
14 | long num3 = 123_000_111L;
15 | long tenSenconds = 10_000L;
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk7/SwitchString.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk7;
2 |
3 | import io.github.biezhi.java8.growing.jdk5.EnumDemo;
4 |
5 | /**
6 | * switch对String的支持
7 | *
8 | * @author biezhi
9 | * @date 2018/2/8
10 | */
11 | public class SwitchString {
12 |
13 | public static void main(String[] args) {
14 | String bis = "java";
15 | switch (bis) {
16 | case "java":
17 | break;
18 | case "python":
19 | break;
20 | case "ruby":
21 | break;
22 | default:
23 | break;
24 | }
25 |
26 | EnumDemo enumDemo = EnumDemo.GREEN;
27 |
28 | switch (enumDemo) {
29 | case RED:
30 | break;
31 | case YELLOW:
32 | break;
33 | default:
34 | break;
35 | }
36 |
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk7/TryWithResource.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk7;
2 |
3 | import io.github.biezhi.java8.growing.jdk6.ScriptEngineDemo;
4 |
5 | import java.io.BufferedReader;
6 | import java.io.FileReader;
7 | import java.io.IOException;
8 |
9 | /**
10 | * try-with-resource
11 | *
12 | * @author biezhi
13 | * @date 2018/2/8
14 | */
15 | public class TryWithResource {
16 |
17 | public static void main(String[] args) {
18 | String path = ScriptEngineDemo.class.getResource("/test.js").getPath();
19 |
20 | try (BufferedReader br = new BufferedReader(new FileReader(path))) {
21 | String str = br.readLine();
22 | while (null != str) {
23 | System.out.println(str);
24 | str = br.readLine();
25 | }
26 | } catch (IOException e) {
27 | e.printStackTrace();
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk7/TypeInference.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk7;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * 类型推断
8 | *
9 | * @author biezhi
10 | * @date 2018/2/8
11 | */
12 | public class TypeInference {
13 |
14 | public static void main(String[] args) {
15 | List list = new ArrayList<>();
16 | list.add("A");
17 |
18 | List extends String> list2 = new ArrayList<>();
19 | list.addAll(list2);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/Base64Demo.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk8;
2 |
3 | import java.nio.charset.StandardCharsets;
4 | import java.util.Base64;
5 |
6 | /**
7 | * Base64 增强
8 | *
9 | * @author biezhi
10 | * @date 2018/2/8
11 | */
12 | public class Base64Demo {
13 |
14 | public static void main(String[] args) {
15 | final String text = "Lets Learn Java 8!";
16 |
17 | final String encoded = Base64
18 | .getEncoder()
19 | .encodeToString(text.getBytes(StandardCharsets.UTF_8));
20 | System.out.println(encoded);
21 |
22 | final String decoded = new String(
23 | Base64.getDecoder().decode(encoded),
24 | StandardCharsets.UTF_8);
25 | System.out.println(decoded);
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/DateTimeAPI.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk8;
2 |
3 | import java.time.*;
4 |
5 | /**
6 | * 新的日期时间 API
7 | *
8 | * @author biezhi
9 | * @date 2018/2/8
10 | */
11 | public class DateTimeAPI {
12 |
13 | public static void main(String[] args) {
14 | // Get the system clock as UTC offset
15 | final Clock clock = Clock.systemUTC();
16 | System.out.println(clock.instant());
17 | System.out.println(clock.millis());
18 |
19 | // Get the local date and local time
20 | final LocalDate date = LocalDate.now();
21 | final LocalDate dateFromClock = LocalDate.now(clock);
22 |
23 | System.out.println(date);
24 | System.out.println(dateFromClock);
25 |
26 | // Get the local date and local time
27 | final LocalTime time = LocalTime.now();
28 | final LocalTime timeFromClock = LocalTime.now(clock);
29 |
30 | System.out.println(time);
31 | System.out.println(timeFromClock);
32 |
33 | // Get the local date/time
34 | final LocalDateTime datetime = LocalDateTime.now();
35 | final LocalDateTime datetimeFromClock = LocalDateTime.now(clock);
36 |
37 | System.out.println(datetime);
38 | System.out.println(datetimeFromClock);
39 |
40 | // Get the zoned date/time
41 | final ZonedDateTime zonedDatetime = ZonedDateTime.now();
42 | final ZonedDateTime zonedDatetimeFromClock = ZonedDateTime.now(clock);
43 | final ZonedDateTime zonedDatetimeFromZone = ZonedDateTime.now(ZoneId.of("America/Los_Angeles"));
44 |
45 | System.out.println(zonedDatetime);
46 | System.out.println(zonedDatetimeFromClock);
47 | System.out.println(zonedDatetimeFromZone);
48 |
49 | // Get duration between two dates
50 | final LocalDateTime from = LocalDateTime.of(2014, Month.APRIL, 16, 0, 0, 0);
51 | final LocalDateTime to = LocalDateTime.of(2015, Month.APRIL, 16, 23, 59, 59);
52 |
53 | final Duration duration = Duration.between(from, to);
54 | System.out.println("Duration in days: " + duration.toDays());
55 | System.out.println("Duration in hours: " + duration.toHours());
56 |
57 |
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/DefaulableFactory.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk8;
2 |
3 | import java.util.function.Supplier;
4 |
5 | public interface DefaulableFactory {
6 | // Interfaces now allow static methods
7 | static Integer create(Supplier supplier) {
8 | return supplier.get();
9 | }
10 | }
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/Functional.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk8;
2 |
3 | /**
4 | * 函数式接口
5 | *
6 | * @author biezhi
7 | * @date 2018/2/8
8 | */
9 | @FunctionalInterface
10 | public interface Functional {
11 |
12 | void method();
13 |
14 | }
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/FunctionalDefaultMethods.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk8;
2 |
3 | /**
4 | * 默认方法
5 | *
6 | * @author biezhi
7 | * @date 2018/2/8
8 | */
9 | @FunctionalInterface
10 | public interface FunctionalDefaultMethods {
11 |
12 | void method();
13 |
14 | default void defaultMethod() {
15 | }
16 | }
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/Lambda.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk8;
2 |
3 | import java.util.Arrays;
4 |
5 | /**
6 | * Lambda 表达式
7 | *
8 | * @author biezhi
9 | * @date 2018/2/8
10 | */
11 | public class Lambda {
12 |
13 | public static void main(String[] args) {
14 | Arrays.asList("a", "b", "d").forEach(System.out::println);
15 |
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/NashornDemo.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk8;
2 |
3 | import javax.script.ScriptEngine;
4 | import javax.script.ScriptEngineManager;
5 | import javax.script.ScriptException;
6 |
7 | /**
8 | * Nashorn JavaScript引擎
9 | *
10 | * @author biezhi
11 | * @date 2018/2/8
12 | */
13 | public class NashornDemo {
14 |
15 | public static void main(String[] args) throws ScriptException {
16 | ScriptEngineManager manager = new ScriptEngineManager();
17 | ScriptEngine engine = manager.getEngineByName("JavaScript");
18 |
19 | System.out.println(engine.getClass().getName());
20 | System.out.println("Result:" + engine.eval("function f() { return 1; }; f() + 1;"));
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/OptionalDemo.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk8;
2 |
3 | import java.util.Optional;
4 |
5 | /**
6 | * Optional
7 | *
8 | * @author biezhi
9 | * @date 2018/2/8
10 | */
11 | public class OptionalDemo {
12 |
13 | public static void main(String[] args) {
14 | Optional fullName = Optional.ofNullable(null);
15 | System.out.println("Full Name is set? " + fullName.isPresent());
16 | System.out.println("Full Name: " + fullName.orElse("[none]"));
17 | System.out.println(fullName.map(s -> "Hey " + s + "!").orElse("Hey Stranger!"));
18 |
19 | Optional firstName = Optional.of("Tom");
20 | System.out.println("First Name is set? " + firstName.isPresent());
21 | System.out.println("First Name: " + firstName.orElseGet(() -> "[none]"));
22 | System.out.println(firstName.map(s -> "Hey " + s + "!").orElse("Hey Stranger!"));
23 | System.out.println();
24 |
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/ParallelArrays.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk8;
2 |
3 | import java.util.Arrays;
4 | import java.util.concurrent.ThreadLocalRandom;
5 |
6 | /**
7 | * 并行数组
8 | *
9 | * @author biezhi
10 | * @date 2018/2/8
11 | */
12 | public class ParallelArrays {
13 |
14 | public static void main(String[] args) {
15 | long[] arrayOfLong = new long[20000];
16 |
17 | Arrays.parallelSetAll(arrayOfLong,
18 | index -> ThreadLocalRandom.current().nextInt(1000000));
19 | Arrays.stream(arrayOfLong).limit(10).forEach(
20 | i -> System.out.print(i + " "));
21 | System.out.println();
22 |
23 | Arrays.parallelSort(arrayOfLong);
24 | Arrays.stream(arrayOfLong).limit(10).forEach(
25 | i -> System.out.print(i + " "));
26 | System.out.println();
27 | }
28 | }
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/Streams.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk8;
2 |
3 | import java.util.Arrays;
4 | import java.util.Collection;
5 |
6 | public class Streams {
7 |
8 | private enum Status {
9 | OPEN, CLOSED
10 | }
11 |
12 | private static final class Task {
13 | private final Status status;
14 | private final Integer points;
15 |
16 | Task(final Status status, final Integer points) {
17 | this.status = status;
18 | this.points = points;
19 | }
20 |
21 | public Integer getPoints() {
22 | return points;
23 | }
24 |
25 | public Status getStatus() {
26 | return status;
27 | }
28 |
29 | @Override
30 | public String toString() {
31 | return String.format("[%s, %d]", status, points);
32 | }
33 | }
34 |
35 | public static void main(String[] args) {
36 | final Collection tasks = Arrays.asList(
37 | new Task(Status.OPEN, 5),
38 | new Task(Status.OPEN, 13),
39 | new Task(Status.CLOSED, 8)
40 | );
41 |
42 | // Calculate total points of all active tasks using sum()
43 | final long totalPointsOfOpenTasks = tasks
44 | .stream()
45 | .filter(task -> task.getStatus() == Status.OPEN)
46 | .mapToInt(Task::getPoints)
47 | .sum();
48 |
49 | System.out.println("Total points: " + totalPointsOfOpenTasks);
50 | }
51 | }
--------------------------------------------------------------------------------
/java8-growing/src/main/java/io/github/biezhi/java8/growing/jdk8/TypeInference.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.growing.jdk8;
2 |
3 | /**
4 | * 更好的类型推断
5 | *
6 | * @author biezhi
7 | * @date 2018/2/8
8 | */
9 | public class TypeInference {
10 |
11 | public static T defaultValue() {
12 | return null;
13 | }
14 |
15 | public T getOrDefault(T value, T defaultValue) {
16 | return (value != null) ? value : defaultValue;
17 | }
18 |
19 | public static void main(String[] args) {
20 | final TypeInference typeInference = new TypeInference<>();
21 | typeInference.getOrDefault("22", TypeInference.defaultValue());
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/java8-growing/src/main/resources/test.js:
--------------------------------------------------------------------------------
1 | function test(){
2 | return Math.round( 11.2 );
3 | }
--------------------------------------------------------------------------------
/java8-lambda/README.md:
--------------------------------------------------------------------------------
1 | # lambda 表达式
2 |
3 | ## 命令式和函数式
4 |
5 | **命令式编程**:命令“机器”如何去做事情(how),这样不管你想要的是什么(what),它都会按照你的命令实现。
6 | **声明式编程**:告诉“机器”你想要的是什么(what),让机器想出如何去做(how)。
7 |
8 | ## 什么是函数式编程?
9 |
10 | 每个人对函数式编程的理解不尽相同。 我的理解是:**在完成一个编程任务时,通过使用不可变的值或函数,对他们进行处理,然后得到另一个值的过程。**
11 | 不同的语言社区往往对各自语言中的特性孤芳自赏。现在谈 Java 程序员如何定义函数式编程还为时尚早,但是,这根本不重要!
12 | 我们关心的是如何写出好代码,而不是符合函数式编程风格的代码。
13 |
14 | ## 行为参数化
15 |
16 | 把算法的策略(行为)作为一个参数传递给函数。
17 |
18 | ## lambda 管中窥豹
19 |
20 | * 匿名:它不像普通的方法那样有一个明确的名称:写得少而想得多!
21 | * 函数:Lambda函数不像方法那样属于某个特定的类。但和方法一样,Lambda有参数列表、函数主体、返回类型,还可能有可以抛出的异常列表。
22 | * 传递:Lambda表达式可以作为参数传递给方法或存储在变量中。
23 | * 简洁:无需像匿名类那样写很多模板代码。
24 |
25 | ## 函数描述符
26 |
27 | 函数式接口的抽象方法的签名基本上就是Lambda表达式的签名,这种抽象方法叫作函数描述符。
28 |
29 | ## 函数式接口,类型推断
30 |
31 | 函数式接口定义且只定义了一个抽象方法,因为抽象方法的签名可以描述Lambda表达式的签名。
32 | 函数式接口的抽象方法的签名称为函数描述符。
33 | 所以为了应用不同的Lambda表达式,你需要一套能够描述常见函数描述符的函数式接口。
34 |
35 | ## Java 8中的常用函数式接口
36 |
37 | | 函数式接口 | 函数描述符 | 原始类型特化 |
38 | |:-----:|:--------|:-------|
39 | | `Predicate` | `T->boolean` | `IntPredicate,LongPredicate, DoublePredicate` |
40 | | `Consumer` | `T->void` | `IntConsumer,LongConsumer, DoubleConsumer` |
41 | | `Function` | `T->R` | `IntFunction, IntToDoubleFunction,`
`IntToLongFunction, LongFunction,`
`LongToDoubleFunction, LongToIntFunction, `
`DoubleFunction, ToIntFunction, `
`ToDoubleFunction, ToLongFunction` |
42 | | `Supplier` | `()->T` | `BooleanSupplier,IntSupplier, LongSupplier, DoubleSupplier` |
43 | | `UnaryOperator` | `T->T` | `IntUnaryOperator, LongUnaryOperator, DoubleUnaryOperator` |
44 | | `BinaryOperator` | `(T,T)->T` | `IntBinaryOperator, LongBinaryOperator, DoubleBinaryOperator` |
45 | | `BiPredicate` | `(L,R)->boolean` | |
46 | | `BiConsumer` | `(T,U)->void` | `ObjIntConsumer, ObjLongConsumer, ObjDoubleConsumer` |
47 | | `BiFunction` | `(T,U)->R` | `ToIntBiFunction, ToLongBiFunction, ToDoubleBiFunction` |
48 |
49 |
50 | ## Lambdas及函数式接口的例子
51 |
52 | | 使用案例 | Lambda 的例子 | 对应的函数式接口 |
53 | |:-----:|:--------|:-------|
54 | | 布尔表达式 | `(List list) -> list.isEmpty()` | `Predicate>` |
55 | | 创建对象 | `() -> new Project()` | `Supplier` |
56 | | 消费一个对象 | `(Project p) -> System.out.println(p.getStars())` | `Consumer` |
57 | | 从一个对象中选择/提取 | `(int a, int b) -> a * b` | `IntBinaryOperator` |
58 | | 比较两个对象 | `(Project p1, Project p2) -> p1.getStars().compareTo(p2.getStars())` | `Comparator 或 BiFunction `Project, Integer> 或 ToIntBiFunction` |
59 |
60 | ## 方法引用
61 |
62 | 方法引用让你可以重复使用现有的方法定义,并像Lambda一样传递它们。
63 |
64 | ## 本节课小结
65 |
66 | - lambda 表达式可以理解为一种匿名函数:它没有名称,但有参数列表、函数主体、返回 类型,可能还有一个可以抛出的异常的列表。
67 | - lambda 表达式让你可以简洁地传递代码。
68 | - 函数式接口就是仅仅声明了一个抽象方法的接口。
69 | - 只有在接受函数式接口的地方才可以使用 lambda 表达式。
70 | - lambda 表达式允许你直接内联,为函数式接口的抽象方法提供实现,并且将整个表达式作为函数式接口的一个实例。
71 | - Java 8自带一些常用的函数式接口,放在 `java.util.function` 包里,包括 `Predicate`、`Function`、`Supplier`、`Consumer` 和 `BinaryOperator`。
72 | - Lambda表达式所需要代表的类型称为目标类型。
73 | - 方法引用让你重复使用现有的方法实现并直接传递它们。
74 | - `Comparator``、`Predicate` 和 `Function` 等函数式接口都有几个可以用来结合 lambda 表达式的默认方法。
--------------------------------------------------------------------------------
/java8-lambda/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | learn-java8
7 | io.github.biezhi
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | java8-lambda
13 |
14 |
15 |
--------------------------------------------------------------------------------
/java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson1/FilterProjects.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.lambda.lesson1;
2 |
3 | import io.github.biezhi.java8.lambda.lesson1.predicate.ProjectLanguagePredicate;
4 | import io.github.biezhi.java8.lambda.lesson1.predicate.ProjectStarPredicate;
5 |
6 | import java.util.ArrayList;
7 | import java.util.Comparator;
8 | import java.util.List;
9 | import java.util.function.Predicate;
10 |
11 | /**
12 | * 过滤 Project
13 | *
14 | * @author biezhi
15 | * @date 2018/2/9
16 | */
17 | public class FilterProjects {
18 |
19 | /**
20 | * 过滤 Java 项目
21 | *
22 | * @param projects
23 | * @return
24 | */
25 | public static List filterJavaProjects(List projects) {
26 | List result = new ArrayList<>();
27 | for (Project project : projects) {
28 | if ("java".equals(project.getLanguage())) {
29 | result.add(project);
30 | }
31 | }
32 | return result;
33 | }
34 |
35 | /**
36 | * 按语言过滤
37 | *
38 | * @param projects
39 | * @param language
40 | * @return
41 | */
42 | public static List filterLanguageProjects(List projects, String language) {
43 | List result = new ArrayList<>();
44 | for (Project project : projects) {
45 | if (language.equals(project.getLanguage())) {
46 | result.add(project);
47 | }
48 | }
49 | return result;
50 | }
51 |
52 | /**
53 | * 按语言和 star 数过滤
54 | *
55 | * @param projects
56 | * @param language
57 | * @param stars
58 | * @return
59 | */
60 | public static List filterLanguageAndStarProjects(List projects, String language, int stars) {
61 | List result = new ArrayList<>();
62 | for (Project project : projects) {
63 | if (language.equals(project.getLanguage()) && project.getStars() > stars) {
64 | result.add(project);
65 | }
66 | }
67 | return result;
68 | }
69 |
70 | /**
71 | * 按照断言条件过滤
72 | *
73 | * @param projects
74 | * @param projectPredicate
75 | * @return
76 | */
77 | public static List filterProjects(List projects, ProjectPredicate projectPredicate) {
78 | List result = new ArrayList<>();
79 | for (Project project : projects) {
80 | if (projectPredicate.test(project)) {
81 | result.add(project);
82 | }
83 | }
84 | return result;
85 | }
86 |
87 | public static List filter(List list, Predicate predicate){
88 | List result = new ArrayList<>();
89 | for (T t : list) {
90 | if(predicate.test(t)){
91 | result.add(t);
92 | }
93 | }
94 | return result;
95 | }
96 |
97 | public static void main(String[] args) {
98 | List data = new ArrayList<>();
99 |
100 | data.add(Project.builder().name("Blade").language("java").author("biezhi")
101 | .stars(3500).description("Lightning fast and elegant mvc framework for Java8").build());
102 |
103 | data.add(Project.builder().name("Tale").language("java").author("biezhi")
104 | .stars(2600).description("Best beautiful java blog, worth a try").build());
105 |
106 | data.add(Project.builder().name("Vue.js").language("js").author("yyx990803")
107 | .stars(83000).description("A progressive, incrementally-adoptable JavaScript framework for building UI on the web.").build());
108 |
109 | data.add(Project.builder().name("Flask").language("python").author("pallets")
110 | .stars(10500).description("The Python micro framework for building web applications").build());
111 |
112 | data.add(Project.builder().name("Elves").language("java").author("biezhi")
113 | .stars(200).description("Spider").build());
114 |
115 | List projects = filterJavaProjects(data);
116 |
117 | projects = filterLanguageProjects(data, "python");
118 |
119 | projects = filterLanguageAndStarProjects(data, "js", 1000);
120 |
121 | projects = filterProjects(data, new ProjectLanguagePredicate("python"));
122 |
123 | projects = filterProjects(data, new ProjectStarPredicate(1000));
124 |
125 | System.out.println(projects.size());
126 |
127 | // JButton jButton = null;
128 | // jButton.addActionListener(e -> System.out.println("按钮被按下了"));
129 |
130 | // 1. 值参数化:啰嗦、死板
131 | // 2. 行为参数化:简洁、灵活
132 |
133 |
134 | List filter = filter(data, project -> project.getStars() > 1000);
135 |
136 | data.sort(Comparator.comparing(Project::getStars));
137 |
138 | System.out.println(data);
139 |
140 | Runnable task = () -> System.out.println("Hello World");
141 |
142 | Thread t = new Thread(task);
143 | t.start();
144 |
145 | }
146 |
147 | }
148 |
--------------------------------------------------------------------------------
/java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson1/Project.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.lambda.lesson1;
2 |
3 | import lombok.Builder;
4 | import lombok.Data;
5 |
6 | /**
7 | * 项目
8 | *
9 | * @author biezhi
10 | * @date 2018/2/9
11 | */
12 | @Data
13 | @Builder
14 | public class Project {
15 |
16 | /**
17 | * 项目名称
18 | */
19 | private String name;
20 |
21 | /**
22 | * 编程语言
23 | */
24 | private String language;
25 |
26 | /**
27 | * star 数
28 | */
29 | private Integer stars;
30 |
31 | /**
32 | * 描述
33 | */
34 | private String description;
35 |
36 | /**
37 | * 作者
38 | */
39 | private String author;
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson1/ProjectPredicate.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.lambda.lesson1;
2 |
3 | /**
4 | * 项目过滤接口
5 | *
6 | * @author biezhi
7 | * @date 2018/2/9
8 | */
9 | public interface ProjectPredicate {
10 |
11 | boolean test(Project project);
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson1/predicate/ProjectLanguagePredicate.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.lambda.lesson1.predicate;
2 |
3 | import io.github.biezhi.java8.lambda.lesson1.Project;
4 | import io.github.biezhi.java8.lambda.lesson1.ProjectPredicate;
5 |
6 | /**
7 | * 按编程语言过滤
8 | *
9 | * @author biezhi
10 | * @date 2018/2/9
11 | */
12 | public class ProjectLanguagePredicate implements ProjectPredicate {
13 |
14 | private String language;
15 |
16 | public ProjectLanguagePredicate(String language) {
17 | this.language = language;
18 | }
19 |
20 | @Override
21 | public boolean test(Project project) {
22 | return language.equals(project.getLanguage());
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson1/predicate/ProjectStarPredicate.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.lambda.lesson1.predicate;
2 |
3 | import io.github.biezhi.java8.lambda.lesson1.Project;
4 | import io.github.biezhi.java8.lambda.lesson1.ProjectPredicate;
5 |
6 | /**
7 | * 按 star 数过滤
8 | *
9 | * @author biezhi
10 | * @date 2018/2/9
11 | */
12 | public class ProjectStarPredicate implements ProjectPredicate {
13 |
14 | private Integer stars;
15 |
16 | public ProjectStarPredicate(Integer stars) {
17 | this.stars = stars;
18 | }
19 |
20 | @Override
21 | public boolean test(Project project) {
22 | return project.getStars() > stars;
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson2/FunctionalDemo.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.lambda.lesson2;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import java.util.UUID;
6 | import java.util.function.*;
7 |
8 | /**
9 | * 函数式接口示例
10 | *
11 | * @author biezhi
12 | * @date 2018/2/10
13 | */
14 | public class FunctionalDemo {
15 |
16 | /**
17 | * 断言
18 | */
19 | public void predicate() {
20 | Predicate namesStartingWithS = name -> name.startsWith("s");
21 | boolean hello = namesStartingWithS.test("Hello");
22 | // false
23 | }
24 |
25 | /**
26 | * 消费数据
27 | */
28 | public void consumer() {
29 | Consumer messageConsumer = message -> System.out.println(message);
30 | messageConsumer.accept("Learn Java8"); // Learn Java8"
31 |
32 | }
33 |
34 | /**
35 | * 转换
36 | */
37 | public void function() {
38 | Function toUpperCase = name -> name.toUpperCase();
39 | toUpperCase.apply("Java"); // Java
40 | }
41 |
42 | /**
43 | * 提供数据
44 | */
45 | public void supplier() {
46 | Supplier uuidGenerator = () -> UUID.randomUUID().toString();
47 | System.out.println(uuidGenerator.get());
48 |
49 | }
50 |
51 | public static void main(String[] args) {
52 |
53 | List list = new ArrayList<>();
54 | for (int i = 300; i < 400; i++) {
55 | list.add(i);
56 | }
57 |
58 | IntPredicate evenNumbers = (int i) -> i % 2 == 0;
59 | evenNumbers.test(1000);
60 |
61 | Predicate oddNumbers = (Integer i) -> i % 2 == 1;
62 | oddNumbers.test(1000);
63 |
64 | Function add1 = x -> x + 1;
65 | Function concat = x -> x + 1;
66 |
67 | Integer two = add1.apply(1); //yields 2
68 | String answer = concat.apply("0 + 1 = "); // "0 + 1 = 1"
69 |
70 | BinaryOperator sum = (a, b) -> a + b;
71 | Integer res = sum.apply(1, 2); // 3
72 |
73 | BinaryOperator> compose = (f, g) -> x -> g.apply(f.apply(x));
74 |
75 | UnaryOperator add2 = n -> n + 1;
76 | UnaryOperator concat1 = s -> s + 1;
77 | Function> sum2 = x -> y -> x + y;
78 | UnaryOperator sum10 = sum2.apply(10);
79 |
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson3/ConstructorReference.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.lambda.lesson3;
2 |
3 | import java.util.function.Supplier;
4 |
5 | /**
6 | * 构造器引用
7 | *
8 | * 对于一个现有构造函数, 你可以利用它的名称和关键字 new 来创建它的一个引用: ClassName::new。
9 | * 它的功能与指向静态方法的引用类似。
10 | *
11 | * @author biezhi
12 | * @date 2018/2/10
13 | */
14 | public class ConstructorReference {
15 |
16 | public static void main(String[] args) {
17 | //构造器引用
18 | //根据参数列表自动匹配构造器
19 | Supplier sup = ConstructorReference::new;
20 | ConstructorReference constructorReference = sup.get();
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson3/DoneByYou.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.lambda.lesson3;
2 |
3 | import java.util.List;
4 | import java.util.function.BiPredicate;
5 | import java.util.function.Function;
6 |
7 | /**
8 | * 由你完成的
9 | *
10 | * 下列Lambda表达式的等效方法引用是什么
11 | *
12 | * @author biezhi
13 | * @date 2018/2/10
14 | */
15 | public class DoneByYou {
16 |
17 | public static void main(String[] args) {
18 | Function stringToInteger = (String s) -> Integer.parseInt(s);
19 | BiPredicate, String> contains = (list, element) -> list.contains(element);
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson3/LambdaException.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.lambda.lesson3;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.IOException;
5 | import java.util.function.Function;
6 |
7 | /**
8 | * lambda 中有异常
9 | *
10 | * 任何函数式接口都不允许抛出受检异常
11 | *
12 | * sf上这个问题的一些讨论:https://stackoverflow.com/questions/18198176/java-8-lambda-function-that-throws-exception
13 | *
14 | * @author biezhi
15 | * @date 2018/2/10
16 | */
17 | public class LambdaException {
18 |
19 | public static void main(String[] args) {
20 | Function f = (BufferedReader b) -> {
21 | try {
22 | return b.readLine();
23 | } catch (IOException e) {
24 | throw new RuntimeException(e);
25 | }
26 | };
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson3/Lambdas.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.lambda.lesson3;
2 |
3 | import io.github.biezhi.java8.lambda.lesson1.Project;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 | import java.util.function.Function;
8 | import java.util.function.Predicate;
9 |
10 | /**
11 | * lambdas
12 | *
13 | * @author biezhi
14 | * @date 2018/2/10
15 | */
16 | public class Lambdas {
17 |
18 | public static List buildData() {
19 | List data = new ArrayList<>();
20 |
21 | data.add(Project.builder().name("Blade").language("java").author("biezhi")
22 | .stars(3500).description("Lightning fast and elegant mvc framework for Java8").build());
23 |
24 | data.add(Project.builder().name("Tale").language("java").author("biezhi")
25 | .stars(2600).description("Best beautiful java blog, worth a try").build());
26 |
27 | data.add(Project.builder().name("Vue.js").language("js").author("yyx990803")
28 | .stars(83000).description("A progressive, incrementally-adoptable JavaScript framework for building UI on the web.").build());
29 |
30 | data.add(Project.builder().name("Flask").language("python").author("pallets")
31 | .stars(10500).description("The Python micro framework for building web applications").build());
32 |
33 | data.add(Project.builder().name("Elves").language("java").author("biezhi")
34 | .stars(200).description("Spider").build());
35 |
36 | return data;
37 | }
38 |
39 | public static void main(String[] args) {
40 | List projects = buildData();
41 | // List names = getNames(projects);
42 | // List names = getNames(projects, project -> project.getStars() > 1000);
43 | List names = getNames(projects, project -> project.getStars() > 1000, project -> project.getDescription());
44 | List stars = getNames(projects, project -> project.getStars() > 1000, ProjectFunction.buildStarFunction());
45 | System.out.println(stars);
46 | // names.forEach(name -> System.out.println(name));
47 | }
48 |
49 | public static List getNames(List projects) {
50 | List names = new ArrayList<>();
51 | for (Project project : projects) {
52 | names.add(project.getName());
53 | }
54 | return names;
55 | }
56 |
57 | public static List getNames(List projects, Predicate predicate) {
58 | List names = new ArrayList<>();
59 | for (Project project : projects) {
60 | if (predicate.test(project)) {
61 | names.add(project.getName());
62 | }
63 | }
64 | return names;
65 | }
66 |
67 | public static List getNames(List projects, Predicate predicate, Function function) {
68 | List names = new ArrayList<>();
69 | for (Project project : projects) {
70 | if (predicate.test(project)) {
71 | names.add(function.apply(project));
72 | }
73 | }
74 | return names;
75 | }
76 |
77 | }
78 |
79 | interface ProjectFunction extends Function {
80 |
81 | static ProjectFunction buildStarFunction() {
82 | return Project::getStars;
83 | }
84 |
85 | }
--------------------------------------------------------------------------------
/java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson3/MethodReference.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.lambda.lesson3;
2 |
3 | import io.github.biezhi.java8.lambda.lesson1.Project;
4 |
5 | import java.util.Arrays;
6 | import java.util.List;
7 | import java.util.function.Predicate;
8 |
9 | import static java.util.stream.Collectors.toList;
10 |
11 | /**
12 | * 方法引用
13 | *
14 | * 1. 指向静态方法的方法引用
15 | * 2. 指向现有对象的实例方法的方法引用
16 | *
17 | * @author biezhi
18 | * @date 2018/2/10
19 | */
20 | public class MethodReference {
21 |
22 | public static List findNumbers(List numbers, Predicate filter) {
23 | List numbersFound = numbers
24 | .stream()
25 | .filter(filter)
26 | .collect(toList());
27 |
28 | return numbersFound;
29 | }
30 |
31 | public static boolean multipleOf3(Integer number) {
32 | return (number % 3) == 0;
33 | }
34 |
35 | public static void main(String[] args) {
36 | List numbers = Arrays.asList(1, 3, 6, 8, 9, 12, 14, 15);
37 |
38 | List multiplesOf3 = findNumbers(numbers, MethodReference::multipleOf3);
39 | System.out.println(multiplesOf3.contains(3));
40 |
41 | Project project = Project.builder().name("Blade").build();
42 | Arrays.asList(project).stream()
43 | .map(Project::getName)
44 | .count();
45 |
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/java8-lambda/src/main/java/io/github/biezhi/java8/lambda/lesson3/OtherReference.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.lambda.lesson3;
2 |
3 | import java.util.function.Function;
4 |
5 | /**
6 | * 数组引用
7 | *
8 | * @author biezhi
9 | * @date 2018/2/10
10 | */
11 | public class OtherReference {
12 |
13 | public static void main(String[] args) {
14 | Function fun = x -> new String[x];
15 | String[] strs = fun.apply(10);
16 | System.out.println(strs.length);
17 |
18 | Function fun1 = String[]::new;
19 | strs = fun1.apply(20);
20 | System.out.println(strs.length);
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/java8-nashorn/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | learn-java8
7 | io.github.biezhi
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | java8-nashorn
13 |
14 |
15 |
--------------------------------------------------------------------------------
/java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn1.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.nashorn;
2 |
3 | import javax.script.Invocable;
4 | import javax.script.ScriptEngine;
5 | import javax.script.ScriptEngineManager;
6 | import java.io.FileReader;
7 | import java.time.LocalDateTime;
8 | import java.util.Date;
9 |
10 | /**
11 | * Calling javascript functions from java with nashorn.
12 | *
13 | * @author Benjamin Winterberg
14 | */
15 | public class Nashorn1 {
16 |
17 | public static void main(String[] args) throws Exception {
18 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
19 | engine.eval(new FileReader("java8-nashorn/src/main/resources/nashorn1.js"));
20 |
21 | Invocable invocable = (Invocable) engine;
22 | Object result = invocable.invokeFunction("fun1", "Peter Parker");
23 | System.out.println(result);
24 | System.out.println(result.getClass());
25 |
26 | invocable.invokeFunction("fun2", new Date());
27 | invocable.invokeFunction("fun2", LocalDateTime.now());
28 | invocable.invokeFunction("fun2", new Person());
29 | }
30 |
31 | }
--------------------------------------------------------------------------------
/java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn10.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.nashorn;
2 |
3 | import jdk.nashorn.api.scripting.NashornScriptEngine;
4 |
5 | import javax.script.ScriptEngineManager;
6 | import javax.script.ScriptException;
7 | import java.util.concurrent.TimeUnit;
8 |
9 | /**
10 | * @author Benjamin Winterberg
11 | */
12 | public class Nashorn10 {
13 |
14 | public static void main(String[] args) throws ScriptException, NoSuchMethodException {
15 | NashornScriptEngine engine = (NashornScriptEngine) new ScriptEngineManager().getEngineByName("nashorn");
16 | engine.eval("load('java8-nashorn/src/main/resources/nashorn10.js')");
17 |
18 | long t0 = System.nanoTime();
19 |
20 | for (int i = 0; i < 100000; i++) {
21 | engine.invokeFunction("testPerf");
22 | }
23 |
24 | long took = System.nanoTime() - t0;
25 | System.out.format("Elapsed time: %d ms", TimeUnit.NANOSECONDS.toMillis(took));
26 | }
27 | }
--------------------------------------------------------------------------------
/java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn11.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.nashorn;
2 |
3 | import jdk.nashorn.api.scripting.NashornScriptEngine;
4 |
5 | import javax.script.Bindings;
6 | import javax.script.ScriptContext;
7 | import javax.script.ScriptEngineManager;
8 | import javax.script.ScriptException;
9 | import javax.script.SimpleBindings;
10 | import javax.script.SimpleScriptContext;
11 |
12 | /**
13 | * @author Benjamin Winterberg
14 | */
15 | public class Nashorn11 {
16 |
17 | public static void main(String[] args) throws Exception {
18 | // test1();
19 | // test2();
20 | // test3();
21 | // test4();
22 | // test5();
23 | // test6();
24 | // test7();
25 | test8();
26 | }
27 |
28 | private static void test8() throws ScriptException {
29 | NashornScriptEngine engine = createEngine();
30 |
31 | engine.eval("var obj = { foo: 23 };");
32 |
33 | ScriptContext defaultContext = engine.getContext();
34 | Bindings defaultBindings = defaultContext.getBindings(ScriptContext.ENGINE_SCOPE);
35 |
36 | SimpleScriptContext context1 = new SimpleScriptContext();
37 | context1.setBindings(defaultBindings, ScriptContext.ENGINE_SCOPE);
38 |
39 | SimpleScriptContext context2 = new SimpleScriptContext();
40 | context2.getBindings(ScriptContext.ENGINE_SCOPE).put("obj", defaultBindings.get("obj"));
41 |
42 | engine.eval("obj.foo = 44;", context1);
43 | engine.eval("print(obj.foo);", context1);
44 | engine.eval("print(obj.foo);", context2);
45 | }
46 |
47 | private static void test7() throws ScriptException {
48 | NashornScriptEngine engine = createEngine();
49 |
50 | engine.eval("var foo = 23;");
51 |
52 | ScriptContext defaultContext = engine.getContext();
53 | Bindings defaultBindings = defaultContext.getBindings(ScriptContext.ENGINE_SCOPE);
54 |
55 | SimpleScriptContext context1 = new SimpleScriptContext();
56 | context1.setBindings(defaultBindings, ScriptContext.ENGINE_SCOPE);
57 |
58 | SimpleScriptContext context2 = new SimpleScriptContext();
59 | context2.getBindings(ScriptContext.ENGINE_SCOPE).put("foo", defaultBindings.get("foo"));
60 |
61 | engine.eval("foo = 44;", context1);
62 | engine.eval("print(foo);", context1);
63 | engine.eval("print(foo);", context2);
64 | }
65 |
66 | private static void test6() throws ScriptException {
67 | NashornScriptEngine engine = createEngine();
68 |
69 | ScriptContext defaultContext = engine.getContext();
70 | defaultContext.getBindings(ScriptContext.GLOBAL_SCOPE).put("foo", "hello");
71 |
72 | ScriptContext customContext = new SimpleScriptContext();
73 | customContext.setBindings(defaultContext.getBindings(ScriptContext.ENGINE_SCOPE), ScriptContext.ENGINE_SCOPE);
74 |
75 | Bindings bindings = new SimpleBindings();
76 | bindings.put("foo", "world");
77 | customContext.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);
78 |
79 | // engine.eval("foo = 23;"); // overrides foo in all contexts, why???
80 |
81 | engine.eval("print(foo)"); // hello
82 | engine.eval("print(foo)", customContext); // world
83 | engine.eval("print(foo)", defaultContext); // hello
84 | }
85 |
86 | private static void test5() throws ScriptException {
87 | NashornScriptEngine engine = createEngine();
88 |
89 | engine.eval("var obj = { foo: 'foo' };");
90 | engine.eval("function printFoo() { print(obj.foo) };");
91 |
92 | ScriptContext defaultContext = engine.getContext();
93 | Bindings defaultBindings = defaultContext.getBindings(ScriptContext.ENGINE_SCOPE);
94 |
95 | SimpleScriptContext context1 = new SimpleScriptContext();
96 | context1.setBindings(defaultBindings, ScriptContext.ENGINE_SCOPE);
97 |
98 | SimpleScriptContext context2 = new SimpleScriptContext();
99 | context2.setBindings(defaultBindings, ScriptContext.ENGINE_SCOPE);
100 |
101 | engine.eval("obj.foo = 'bar';", context1);
102 | engine.eval("printFoo();", context1);
103 | engine.eval("printFoo();", context2);
104 | }
105 |
106 | private static void test4() throws ScriptException {
107 | NashornScriptEngine engine = createEngine();
108 |
109 | engine.eval("function foo() { print('bar') };");
110 |
111 | ScriptContext defaultContext = engine.getContext();
112 | Bindings defaultBindings = defaultContext.getBindings(ScriptContext.ENGINE_SCOPE);
113 |
114 | SimpleScriptContext context = new SimpleScriptContext();
115 | context.setBindings(defaultBindings, ScriptContext.ENGINE_SCOPE);
116 |
117 | engine.eval("foo();", context);
118 | System.out.println(context.getAttribute("foo"));
119 | }
120 |
121 | private static void test3() throws ScriptException {
122 | NashornScriptEngine engine = createEngine();
123 |
124 | ScriptContext defaultContext = engine.getContext();
125 | Bindings defaultBindings = defaultContext.getBindings(ScriptContext.ENGINE_SCOPE);
126 |
127 | SimpleScriptContext context = new SimpleScriptContext();
128 | context.setBindings(defaultBindings, ScriptContext.ENGINE_SCOPE);
129 |
130 | engine.eval("function foo() { print('bar') };", context);
131 | engine.eval("foo();", context);
132 |
133 | Bindings bindings = context.getBindings(ScriptContext.ENGINE_SCOPE);
134 | System.out.println(bindings.get("foo"));
135 | System.out.println(context.getAttribute("foo"));
136 | }
137 |
138 | private static void test2() throws ScriptException {
139 | NashornScriptEngine engine = createEngine();
140 | engine.eval("function foo() { print('bar') };");
141 |
142 | SimpleScriptContext context = new SimpleScriptContext();
143 | engine.eval("print(Function);", context);
144 | engine.eval("foo();", context);
145 | }
146 |
147 | private static void test1() throws ScriptException {
148 | NashornScriptEngine engine = createEngine();
149 | engine.eval("function foo() { print('bar') };");
150 | engine.eval("foo();");
151 | }
152 |
153 | private static NashornScriptEngine createEngine() {
154 | return (NashornScriptEngine) new ScriptEngineManager().getEngineByName("nashorn");
155 | }
156 |
157 | }
--------------------------------------------------------------------------------
/java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn2.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.nashorn;
2 |
3 | import jdk.nashorn.api.scripting.ScriptObjectMirror;
4 |
5 | import javax.script.ScriptEngine;
6 | import javax.script.ScriptEngineManager;
7 | import java.io.FileReader;
8 | import java.util.Arrays;
9 |
10 | /**
11 | * Calling java methods from javascript with nashorn.
12 | *
13 | * @author Benjamin Winterberg
14 | */
15 | public class Nashorn2 {
16 |
17 | public static String fun(String name) {
18 | System.out.format("Hi there from Java, %s", name);
19 | return "greetings from java";
20 | }
21 |
22 | public static void fun2(Object object) {
23 | System.out.println(object.getClass());
24 | }
25 |
26 | public static void fun3(ScriptObjectMirror mirror) {
27 | System.out.println(mirror.getClassName() + ": " + Arrays.toString(mirror.getOwnKeys(true)));
28 | }
29 |
30 | public static void fun4(ScriptObjectMirror person) {
31 | System.out.println("Full Name is: " + person.callMember("getFullName"));
32 | }
33 |
34 | public static void main(String[] args) throws Exception {
35 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
36 | engine.eval(new FileReader("java8-nashorn/src/main/resources/nashorn2.js"));
37 | }
38 |
39 | }
--------------------------------------------------------------------------------
/java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn3.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.nashorn;
2 |
3 | import javax.script.ScriptEngine;
4 | import javax.script.ScriptEngineManager;
5 |
6 | /**
7 | * Working with java types from javascript.
8 | *
9 | * @author Benjamin Winterberg
10 | */
11 | public class Nashorn3 {
12 |
13 | public static void main(String[] args) throws Exception {
14 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
15 | engine.eval("load('java8-nashorn/src/main/resources/nashorn3.js')");
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn4.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.nashorn;
2 |
3 | import javax.script.ScriptEngine;
4 | import javax.script.ScriptEngineManager;
5 |
6 | /**
7 | * Working with java types from javascript.
8 | *
9 | * @author Benjamin Winterberg
10 | */
11 | public class Nashorn4 {
12 |
13 | public static void main(String[] args) throws Exception {
14 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
15 | engine.eval("loadWithNewGlobal('java8-nashorn/src/main/resources/nashorn4.js')");
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn5.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.nashorn;
2 |
3 | import javax.script.Invocable;
4 | import javax.script.ScriptEngine;
5 | import javax.script.ScriptEngineManager;
6 |
7 | /**
8 | * Bind java objects to custom javascript objects.
9 | *
10 | * @author Benjamin Winterberg
11 | */
12 | public class Nashorn5 {
13 |
14 | public static void main(String[] args) throws Exception {
15 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
16 | engine.eval("load('java8-nashorn/src/main/resources/nashorn5.js')");
17 |
18 | Invocable invocable = (Invocable) engine;
19 |
20 | Product product = new Product();
21 | product.setName("Rubber");
22 | product.setPrice(1.99);
23 | product.setStock(1037);
24 |
25 | Object result = invocable.invokeFunction("getValueOfGoods", product);
26 | System.out.println(result);
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn6.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.nashorn;
2 |
3 | import jdk.nashorn.api.scripting.ScriptObjectMirror;
4 |
5 | import javax.script.Invocable;
6 | import javax.script.ScriptEngine;
7 | import javax.script.ScriptEngineManager;
8 |
9 | /**
10 | * Using Backbone Models from Nashorn.
11 | *
12 | * @author Benjamin Winterberg
13 | */
14 | public class Nashorn6 {
15 |
16 | public static void main(String[] args) throws Exception {
17 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
18 | engine.eval("load('java8-nashorn/src/main/resources/nashorn6.js')");
19 |
20 | Invocable invocable = (Invocable) engine;
21 |
22 | Product product = new Product();
23 | product.setName("Rubber");
24 | product.setPrice(1.99);
25 | product.setStock(1337);
26 |
27 | ScriptObjectMirror result = (ScriptObjectMirror)
28 | invocable.invokeFunction("calculate", product);
29 | System.out.println(result.get("name") + ": " + result.get("valueOfGoods"));
30 | }
31 |
32 | public static void getProduct(ScriptObjectMirror result) {
33 | System.out.println(result.get("name") + ": " + result.get("valueOfGoods"));
34 | }
35 |
36 | }
--------------------------------------------------------------------------------
/java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn7.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.nashorn;
2 |
3 | import javax.script.Invocable;
4 | import javax.script.ScriptEngine;
5 | import javax.script.ScriptEngineManager;
6 | import javax.script.ScriptException;
7 |
8 | /**
9 | * @author Benjamin Winterberg
10 | */
11 | public class Nashorn7 {
12 |
13 | public static class Person {
14 | private String name;
15 |
16 | public String getName() {
17 | return name;
18 | }
19 |
20 | public void setName(String name) {
21 | this.name = name;
22 | }
23 |
24 | public int getLengthOfName() {
25 | return name.length();
26 | }
27 | }
28 |
29 | public static void main(String[] args) throws ScriptException, NoSuchMethodException {
30 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
31 | engine.eval("function foo(predicate, obj) { return !!(eval(predicate)); };");
32 |
33 | Invocable invocable = (Invocable) engine;
34 |
35 | Person person = new Person();
36 | person.setName("Hans");
37 |
38 | String predicate = "obj.getLengthOfName() >= 4";
39 | Object result = invocable.invokeFunction("foo", predicate, person);
40 | System.out.println(result);
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn8.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.nashorn;
2 |
3 | import jdk.nashorn.api.scripting.NashornScriptEngine;
4 |
5 | import javax.script.ScriptEngineManager;
6 | import javax.script.ScriptException;
7 |
8 | /**
9 | * @author Benjamin Winterberg
10 | */
11 | public class Nashorn8 {
12 | public static void main(String[] args) throws ScriptException, NoSuchMethodException {
13 | NashornScriptEngine engine = (NashornScriptEngine) new ScriptEngineManager().getEngineByName("nashorn");
14 | engine.eval("load('java8-nashorn/src/main/resources/nashorn8.js')");
15 |
16 | engine.invokeFunction("evaluate1"); // [object global]
17 | engine.invokeFunction("evaluate2"); // [object Object]
18 | engine.invokeFunction("evaluate3", "Foobar"); // Foobar
19 | engine.invokeFunction("evaluate3", new Person("John", "Doe")); // [object global] <- ???????
20 | }
21 |
22 | }
--------------------------------------------------------------------------------
/java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Nashorn9.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.nashorn;
2 |
3 | import jdk.nashorn.api.scripting.NashornScriptEngine;
4 |
5 | import javax.script.ScriptEngineManager;
6 | import javax.script.ScriptException;
7 | import java.util.concurrent.TimeUnit;
8 |
9 | /**
10 | * @author Benjamin Winterberg
11 | */
12 | public class Nashorn9 {
13 |
14 | public static void main(String[] args) throws ScriptException, NoSuchMethodException {
15 | NashornScriptEngine engine = (NashornScriptEngine) new ScriptEngineManager().getEngineByName("nashorn");
16 | engine.eval("load('java8-nashorn/src/main/resources/nashorn9.js')");
17 |
18 | long t0 = System.nanoTime();
19 |
20 | double result = 0;
21 | for (int i = 0; i < 1000; i++) {
22 | double num = (double) engine.invokeFunction("testPerf");
23 | result += num;
24 | }
25 |
26 | System.out.println(result > 0);
27 |
28 | long took = System.nanoTime() - t0;
29 | System.out.format("Elapsed time: %d ms", TimeUnit.NANOSECONDS.toMillis(took));
30 | }
31 | }
--------------------------------------------------------------------------------
/java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Person.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.nashorn;
2 |
3 | /**
4 | * @author Benjamin Winterberg
5 | */
6 | public class Person {
7 | public String firstName;
8 | public String lastName;
9 |
10 | public Person() {}
11 |
12 | public Person(String firstName, String lastName) {
13 | this.firstName = firstName;
14 | this.lastName = lastName;
15 | }
16 | }
--------------------------------------------------------------------------------
/java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/Product.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.nashorn;
2 |
3 | import lombok.Data;
4 |
5 | @Data
6 | public class Product {
7 | private String name;
8 | private double price;
9 | private int stock;
10 | private double valueOfGoods;
11 |
12 | }
--------------------------------------------------------------------------------
/java8-nashorn/src/main/java/io/github/biezhi/java8/nashorn/SuperRunner.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.nashorn;
2 |
3 | public class SuperRunner implements Runnable {
4 |
5 | @Override
6 | public void run() {
7 | System.out.println("super run");
8 | }
9 |
10 | }
--------------------------------------------------------------------------------
/java8-nashorn/src/main/resources/nashorn1.js:
--------------------------------------------------------------------------------
1 | var fun1 = function(name) {
2 | print('Hi there from Javascript, ' + name);
3 | return "greetings from javascript";
4 | };
5 |
6 | var fun2 = function (object) {
7 | print("JS Class Definition: " + Object.prototype.toString.call(object));
8 | };
--------------------------------------------------------------------------------
/java8-nashorn/src/main/resources/nashorn10.js:
--------------------------------------------------------------------------------
1 | var results = [];
2 |
3 | var Context = function () {
4 | this.foo = 'bar';
5 | };
6 |
7 | Context.prototype.testArgs = function () {
8 | if (arguments[0]) {
9 | results.push(true);
10 | }
11 | if (arguments[1]) {
12 | results.push(true);
13 | }
14 | if (arguments[2]) {
15 | results.push(true);
16 | }
17 | if (arguments[3]) {
18 | results.push(true);
19 | }
20 | };
21 |
22 | var testPerf = function () {
23 | var context = new Context();
24 | context.testArgs();
25 | context.testArgs(1);
26 | context.testArgs(1, 2);
27 | context.testArgs(1, 2, 3);
28 | context.testArgs(1, 2, 3, 4);
29 | };
--------------------------------------------------------------------------------
/java8-nashorn/src/main/resources/nashorn2.js:
--------------------------------------------------------------------------------
1 | var Nashorn2 = Java.type('io.github.biezhi.java8.nashorn.Nashorn2');
2 | var result = Nashorn2.fun('John Doe');
3 | print('\n' + result);
4 |
5 | Nashorn2.fun2(123);
6 | Nashorn2.fun2(49.99);
7 | Nashorn2.fun2(true);
8 | Nashorn2.fun2("hi there")
9 | Nashorn2.fun2(String("bam"))
10 | Nashorn2.fun2(new Number(23));
11 | Nashorn2.fun2(new Date());
12 | Nashorn2.fun2(new RegExp());
13 | Nashorn2.fun2({foo: 'bar'});
14 |
15 |
16 | print('passing object hash:');
17 | Nashorn2.fun3({
18 | foo: 'bar',
19 | bar: 'foo'
20 | });
21 |
22 |
23 | print('passing custom person object:');
24 |
25 | function Person(firstName, lastName) {
26 | this.firstName = firstName;
27 | this.lastName = lastName;
28 | this.getFullName = function() {
29 | return this.firstName + " " + this.lastName;
30 | }
31 | }
32 |
33 | var person1 = new Person("Peter", "Parker");
34 | Nashorn2.fun3(person1);
35 | Nashorn2.fun4(person1);
--------------------------------------------------------------------------------
/java8-nashorn/src/main/resources/nashorn3.js:
--------------------------------------------------------------------------------
1 | print('------------------');
2 | print('IntArray:');
3 |
4 | var IntArray = Java.type('int[]');
5 |
6 | var array = new IntArray(5);
7 | array[0] = 5;
8 | array[1] = 4;
9 | array[2] = 3;
10 | array[3] = 2;
11 | array[4] = 1;
12 |
13 | try {
14 | array[5] = 23;
15 | } catch (e) {
16 | print(e.message);
17 | }
18 |
19 | array[0] = "17";
20 | print(array[0]);
21 |
22 | array[0] = "wrong type";
23 | print(array[0]);
24 |
25 | array[0] = "17.3";
26 | print(array[0]);
27 |
28 | print('------------------');
29 |
30 | for (var i in array) print(i);
31 |
32 | print('------------------');
33 |
34 | for each (var val in array) print(val);
35 |
36 | print('------------------');
37 | print('ArrayList:');
38 |
39 | var ArrayList = Java.type('java.util.ArrayList');
40 |
41 | var list = new ArrayList();
42 | list.add('a');
43 | list.add('b');
44 | list.add('c');
45 |
46 | for each (var el in list) print(el);
47 |
48 |
49 | print('------------------');
50 | print('HashMap:');
51 |
52 | var HashMap = Java.type('java.util.HashMap');
53 |
54 | var map = new HashMap();
55 | map.put('foo', 'foo1');
56 | map.put('bar', 'bar1');
57 |
58 | for each(var e in map.keySet()) print(e);
59 |
60 | for each(var e in map.values()) print(e);
61 |
62 |
63 | print('------------------');
64 | print('Streams:');
65 |
66 | var list2 = new ArrayList();
67 | list2.add("ddd2");
68 | list2.add("aaa2");
69 | list2.add("bbb1");
70 | list2.add("aaa1");
71 | list2.add("bbb3");
72 | list2.add("ccc");
73 | list2.add("bbb2");
74 | list2.add("ddd1");
75 |
76 | list2
77 | .stream()
78 | .filter(function(el) {
79 | return el.startsWith("aaa");
80 | })
81 | .sorted()
82 | .forEach(function(el) {
83 | print(el);
84 | });
85 |
86 |
87 |
88 | print('------------------');
89 | print('Extend:');
90 |
91 | var Runnable = Java.type('java.lang.Runnable');
92 | var Printer = Java.extend(Runnable, {
93 | run: function() {
94 | print('This was printed from a seperate thread.');
95 | }
96 | });
97 |
98 | var Thread = Java.type('java.lang.Thread');
99 | new Thread(new Printer()).start();
100 |
101 | new Thread(function() {
102 | print('this was printed from another thread');
103 | }).start();
104 |
105 |
106 | print('------------------');
107 | print('Parameter Overload:');
108 |
109 | var System = Java.type('java.lang.System');
110 |
111 | System.out.println(10);
112 | System.out["println"](11.0);
113 | System.out["println(double)"](12);
114 |
115 | print('------------------');
116 | print('JavaBeans:');
117 |
118 | var Date = Java.type('java.util.Date');
119 | var date = new Date();
120 | date.year += 1900;
121 | System.out.println(date.year);
--------------------------------------------------------------------------------
/java8-nashorn/src/main/resources/nashorn4.js:
--------------------------------------------------------------------------------
1 | // function literal with no braces
2 |
3 | function sqr(x) x * x;
4 |
5 | print(sqr(3));
6 |
7 |
8 | // for each
9 |
10 | var array = [1, 2, 3, 4];
11 | for each (var num in array) print(num);
12 |
13 |
14 | // object literals in constructors
15 |
16 | var runnable = new java.lang.Runnable() {
17 | run: function() {
18 | print('on the run');
19 | }
20 | };
21 |
22 | runnable.run();
23 |
24 |
25 | // bind properties
26 |
27 | var o1 = {};
28 | var o2 = { foo: 'bar'};
29 |
30 | Object.bindProperties(o1, o2);
31 |
32 | print(o1.foo);
33 | o1.foo = 'BAM';
34 | print(o2.foo);
35 |
36 |
37 | // string trim
38 |
39 | print(" hehe".trimLeft());
40 | print("hehe ".trimRight() + "he");
41 |
42 |
43 | // whereis
44 | print(__FILE__, __LINE__, __DIR__);
45 |
46 |
47 | // java import
48 |
49 | var imports = new JavaImporter(java.io, java.lang);
50 | with (imports) {
51 | var file = new File(__FILE__);
52 | System.out.println(file.getAbsolutePath());
53 | // /path/to/my/script.js
54 | }
55 |
56 |
57 | // convert iterable to js array
58 |
59 | var list = new java.util.ArrayList();
60 | list.add("s1");
61 | list.add("s2");
62 | list.add("s3");
63 |
64 | var jsArray = Java.from(list);
65 | print(jsArray);
66 | print(Object.prototype.toString.call(jsArray));
67 |
68 |
69 | // convert js array to java array
70 |
71 | var javaArray = Java.to([3, 5, 7, 11], "int[]");
72 | print(Object.prototype.toString.call(javaArray));
73 |
74 |
75 | // calling super
76 |
77 | var SuperRunner = Java.type('io.github.biezhi.java8.nashorn.SuperRunner');
78 | var Runner = Java.extend(SuperRunner);
79 |
80 | var runner = new Runner() {
81 | run: function() {
82 | Java.super(runner).run();
83 | print('on my run');
84 | }
85 | }
86 | runner.run();
87 |
88 |
89 |
90 | // load
91 |
92 | load('http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js');
93 |
94 | var odds = _.filter([1, 2, 3, 4, 5, 6], function (num) {
95 | return num % 2 == 1;
96 | });
97 |
98 | print(odds);
--------------------------------------------------------------------------------
/java8-nashorn/src/main/resources/nashorn5.js:
--------------------------------------------------------------------------------
1 | function Product(name) {
2 | this.name = name;
3 | }
4 |
5 | Product.prototype.stock = 0;
6 | Product.prototype.price = 0;
7 | Product.prototype.getValueOfGoods = function() {
8 | return this.stock * this.price;
9 | };
10 |
11 | var product = new Product('Pencil');
12 | product.price = 4.99;
13 | product.stock = 78;
14 |
15 | print('Value of Goods: ' + product.getValueOfGoods());
16 |
17 |
18 | var getValueOfGoods = function(javaProduct) {
19 | var jsProduct = new Product();
20 | Object.bindProperties(jsProduct, javaProduct);
21 | return jsProduct.getValueOfGoods();
22 | };
--------------------------------------------------------------------------------
/java8-nashorn/src/main/resources/nashorn6.js:
--------------------------------------------------------------------------------
1 | load('http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js');
2 | load('http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js');
3 |
4 |
5 | // simple backbone model:
6 | // valueOfGoods will automatically be calculated when stock or price changes
7 | var Product = Backbone.Model.extend({
8 | defaults: {
9 | stock: 0,
10 | price: 0.0,
11 | name:'',
12 | valueOfGoods: 0.0
13 | },
14 |
15 | initialize: function() {
16 | this.on('change:stock change:price', function() {
17 | var stock = this.get('stock');
18 | var price = this.get('price');
19 | var valueOfGoods = this.getValueOfGoods(stock, price);
20 | this.set('valueOfGoods', valueOfGoods);
21 | });
22 | },
23 |
24 | getValueOfGoods: function(stock, price) {
25 | return stock * price;
26 | }
27 | });
28 |
29 | var product = new Product();
30 | product.set('name', 'Pencil');
31 | product.set('stock', 1000);
32 | product.set('price', 3.99);
33 |
34 |
35 | // pass backbone model to java method
36 | var Nashorn6 = Java.type('io.github.biezhi.java8.nashorn.Nashorn6');
37 | Nashorn6.getProduct(product.attributes);
38 |
39 |
40 | // bind java object to backbone model and pass result back to java
41 | var calculate = function(javaProduct) {
42 | var model = new Product();
43 | model.set('name', javaProduct.name);
44 | model.set('price', javaProduct.price);
45 | model.set('stock', javaProduct.stock);
46 | return model.attributes;
47 | };
--------------------------------------------------------------------------------
/java8-nashorn/src/main/resources/nashorn7.js:
--------------------------------------------------------------------------------
1 | function sqrt(x) x * x
2 | print(sqrt(3));
3 |
4 | var array = [1, 2, 3, 4];
5 | for each (var num in array) print(num);
6 |
7 | var runnable = new java.lang.Runnable() {
8 | run: function () {
9 | print('on the run');
10 | }
11 | };
12 |
13 | runnable.run();
14 |
15 | var System = Java.type('java.lang.System');
16 | System.out["println(double)"](12);
17 |
18 | var Arrays = Java.type("java.util.Arrays");
19 | var javaArray = Java.to([2, 3, 7, 11, 14], "int[]");
20 |
21 | Arrays.stream(javaArray)
22 | .filter(function (num) {
23 | return num % 2 === 1;
24 | })
25 | .forEach(function (num) {
26 | print(num);
27 | });
--------------------------------------------------------------------------------
/java8-nashorn/src/main/resources/nashorn8.js:
--------------------------------------------------------------------------------
1 | var evaluate1 = function () {
2 | (function () {
3 | print(eval("this"));
4 | }).call(this);
5 | };
6 |
7 | var evaluate2 = function () {
8 | var context = {};
9 | (function () {
10 | print(eval("this"));
11 | }).call(context);
12 | };
13 |
14 | var evaluate3 = function (context) {
15 | (function () {
16 | print(eval("this"));
17 | }).call(context);
18 | };
--------------------------------------------------------------------------------
/java8-nashorn/src/main/resources/nashorn9.js:
--------------------------------------------------------------------------------
1 | var size = 100000;
2 |
3 | var testPerf = function () {
4 | var result = Math.floor(Math.random() * size) + 1;
5 | for (var i = 0; i < size; i++) {
6 | result += i;
7 | }
8 | return result;
9 | };
--------------------------------------------------------------------------------
/java8-optional/README.md:
--------------------------------------------------------------------------------
1 | # Optional
2 |
3 | ## Optional类的方法
4 |
5 | | 方法 | 描述 |
6 | |:-----:|:-------|
7 | | `empty` | 返回一个空的 Optional 实例 |
8 | | `filter` | 如果值存在并且满足提供的断言, 就返回包含该值的 Optional 对象;否则返回一个空的 Optional 对象 |
9 | | `map` | 如果值存在,就对该值执行提供的 mapping 函数调用 |
10 | | `flatMap` | 如果值存在,就对该值执行提供的 mapping 函数调用,返回一个 Optional 类型的值,否则就返 回一个空的 Optional 对象 |
11 | | `get` | 如果该值存在,将该值用 Optional 封装返回,否则抛出一个 NoSuchElementException 异常 |
12 | | `ifPresent` | 如果值存在,就执行使用该值的方法调用,否则什么也不做 |
13 | | `isPresent` | 如果值存在就返回 true,否则返回 false |
14 | | `of` | 将指定值用 Optional 封装之后返回,如果该值为 null,则抛出一个 NullPointerException 异常 |
15 | | `ofNullable` | 将指定值用 Optional 封装之后返回,如果该值为 null,则返回一个空的 Optional 对象 |
16 | | `orElse` | 如果有值则将其返回,否则返回一个默认值 |
17 | | `orElseGet` | 如果有值则将其返回,否则返回一个由指定的 Supplier 接口生成的值 |
18 | | `orElseThrow` | 如果有值则将其返回,否则抛出一个由指定的 Supplier 接口生成的异常 |
19 |
--------------------------------------------------------------------------------
/java8-optional/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | learn-java8
7 | io.github.biezhi
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | java8-optional
13 |
14 |
15 |
--------------------------------------------------------------------------------
/java8-optional/src/main/java/io/github/biezhi/java8/optional/Address.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.optional;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | /**
9 | * 住址对象
10 | *
11 | * @author biezhi
12 | * @date 2018/2/11
13 | */
14 | @Data
15 | @NoArgsConstructor
16 | @AllArgsConstructor
17 | public class Address {
18 |
19 | /**
20 | * 街道
21 | */
22 | private String street;
23 |
24 | /**
25 | * 门牌
26 | */
27 | private String door;
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/java8-optional/src/main/java/io/github/biezhi/java8/optional/BeforeJava8.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.optional;
2 |
3 | /**
4 | * @author biezhi
5 | * @date 2018/2/11
6 | */
7 | public class BeforeJava8 {
8 |
9 | /**
10 | * Java 8 之前
11 | *
12 | * @param user
13 | */
14 | public void saveUser(User user) {
15 | if (null != user) {
16 | if (null != user.getAddress()) {
17 | // 保存 user
18 | }
19 | }
20 | }
21 |
22 | /**
23 | * 过多的退出语句
24 | *
25 | * @param user
26 | */
27 | public void saveUser2(User user) {
28 | if (null == user) {
29 | return;
30 | }
31 | if (null == user.getAddress()) {
32 | return;
33 | }
34 | // 保存 user
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/java8-optional/src/main/java/io/github/biezhi/java8/optional/OptionalDemo.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.optional;
2 |
3 | import java.util.Optional;
4 | import java.util.Properties;
5 |
6 | /**
7 | * @author biezhi
8 | * @date 2018/2/11
9 | */
10 | public class OptionalDemo {
11 |
12 | /**
13 | * 1. 创建 Optional
14 | */
15 | public void createOptional() {
16 | // 声明一个空的Optional
17 | Optional optionalAddress = Optional.empty();
18 |
19 | // 依据一个非空值创建Optional
20 | Optional optionalAddress2 = Optional.of(new Address());
21 |
22 | // 可接受null的Optional
23 | Optional optionalAddress3 = Optional.ofNullable(new Address());
24 | }
25 |
26 | /**
27 | * 2. 使用 map 从 Optional 对象中提取和转换值
28 | */
29 | public void map() {
30 | Optional addressOptional = Optional.ofNullable(new Address("达尔文路", "88号"));
31 | Optional street = addressOptional.map(Address::getStreet);
32 | }
33 |
34 | /**
35 | * 3. 使用 flatMap 链接 Optional 对象
36 | */
37 | public void flatMap() {
38 | User user = new User();
39 | Optional userOptional = Optional.of(user);
40 | // userOptional.map(user -> user.getOptAddress())
41 | Optional stringOptional = userOptional.flatMap(User::getOptAddress).map(Address::getStreet);
42 |
43 | }
44 |
45 | /**
46 | * 4. 默认行为及解引用 Optional 对象
47 | */
48 | public void defaultValue() {
49 | Optional addressOptional = Optional.ofNullable(null);
50 | String street = addressOptional.map(Address::getStreet).orElse("北京二环");
51 | System.out.println(street);
52 | }
53 |
54 | public static void main(String[] args) {
55 | User user = new User();
56 | user.setUsername("biezhi");
57 | user.setPassword("123456");
58 | user.setOptAddress(Optional.of(new Address("达尔文路", "88号")));
59 | user.setAge(30);
60 |
61 | // Address address1 = null;
62 | // try {
63 | // address1 = user.getOptAddress().filter(address -> address.getDoor().contains("878"))
64 | // .orElseThrow(new Supplier() {
65 | // @Override
66 | // public Throwable get() {
67 | // return new Exception("挂了");
68 | // }
69 | // });
70 | // } catch (Throwable throwable) {
71 | // throwable.printStackTrace();
72 | // }
73 | // System.out.println(address1);
74 |
75 | System.out.println(getStreet(Optional.of(user), 50));
76 | }
77 |
78 | public static String getStreet(Optional user, int minAge) {
79 | return user.filter(u -> u.getAge() >= minAge)
80 | .flatMap(User::getOptAddress)
81 | .map(Address::getStreet)
82 | .orElse("没有");
83 | }
84 |
85 | public static Optional parseInt(String value) {
86 | try {
87 | return Optional.ofNullable(Integer.parseInt(value));
88 | } catch (Exception e) {
89 | return Optional.empty();
90 | }
91 | }
92 |
93 | public int readPoint(Properties props, String name) {
94 | return Optional.ofNullable(props.getProperty(name))
95 | .flatMap(OptionalDemo::parseInt)
96 | .filter(i -> i > 0)
97 | .orElse(0);
98 | }
99 |
100 | }
101 |
--------------------------------------------------------------------------------
/java8-optional/src/main/java/io/github/biezhi/java8/optional/User.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.optional;
2 |
3 | import lombok.Data;
4 |
5 | import java.util.Optional;
6 |
7 | /**
8 | * User
9 | *
10 | * @author biezhi
11 | * @date 2018/2/11
12 | */
13 | @Data
14 | public class User {
15 |
16 | private String username;
17 | private String password;
18 | private Integer age;
19 | private Address address;
20 |
21 | private Optional optAddress;
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/java8-proper/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | learn-java8
7 | io.github.biezhi
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | java8-proper
13 |
14 |
15 |
--------------------------------------------------------------------------------
/java8-stream/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | learn-java8
7 | io.github.biezhi
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | java8-stream
13 |
14 |
15 |
--------------------------------------------------------------------------------
/java8-stream/src/main/java/io/github/biezhi/java8/stream/Project.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.stream;
2 |
3 | import lombok.Builder;
4 | import lombok.Data;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | /**
10 | * 项目
11 | *
12 | * @author biezhi
13 | * @date 2018/2/9
14 | */
15 | @Data
16 | @Builder
17 | public class Project {
18 |
19 | /**
20 | * 项目名称
21 | */
22 | private String name;
23 |
24 | /**
25 | * 编程语言
26 | */
27 | private String language;
28 |
29 | /**
30 | * star 数
31 | */
32 | private Integer stars;
33 |
34 | /**
35 | * 描述
36 | */
37 | private String description;
38 |
39 | /**
40 | * 作者
41 | */
42 | private String author;
43 |
44 | /**
45 | * fork数
46 | */
47 | private Integer forks;
48 |
49 | public static List buildData(){
50 | List data = new ArrayList<>();
51 |
52 | data.add(Project.builder().name("Blade").language("java").author("biezhi")
53 | .stars(3500).forks(2000).description("Lightning fast and elegant mvc framework for Java8").build());
54 |
55 | data.add(Project.builder().name("Tale").language("javascript").author("biezhi")
56 | .stars(2600).forks(2300).description("Best beautiful java blog, worth a try").build());
57 |
58 | data.add(Project.builder().name("Vue.js").language("js").author("yyx990803")
59 | .stars(83000).forks(10322).description("A progressive, incrementally-adoptable JavaScript framework for building UI on the web.").build());
60 |
61 | data.add(Project.builder().name("Flask").language("python").author("pallets")
62 | .stars(10500).forks(3000).description("The Python micro framework for building web applications").build());
63 |
64 | data.add(Project.builder().name("Elves").language("java").author("biezhi")
65 | .stars(200).forks(100).description("Spider").build());
66 |
67 | return data;
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson1/Java7.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.stream.lesson1;
2 |
3 | import io.github.biezhi.java8.stream.Project;
4 |
5 | import java.util.ArrayList;
6 | import java.util.Collections;
7 | import java.util.Comparator;
8 | import java.util.List;
9 |
10 | /**
11 | * @author biezhi
12 | * @date 2018/2/11
13 | */
14 | public class Java7 {
15 |
16 | public static void main(String[] args) {
17 | List result = new ArrayList<>();
18 |
19 | List projects = new ArrayList<>();
20 | for (Project project : projects) {
21 | if(project.getStars() > 1000){
22 | result.add(project);
23 | }
24 | }
25 | Collections.sort(projects, new Comparator() {
26 | @Override
27 | public int compare(Project o1, Project o2) {
28 | return o1.getStars().compareTo(o2.getStars());
29 | }
30 | });
31 |
32 | List names = new ArrayList<>();
33 |
34 | for (Project project : projects) {
35 | names.add(project.getName());
36 | }
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson1/Java8.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.stream.lesson1;
2 |
3 | import io.github.biezhi.java8.stream.Project;
4 |
5 | import java.util.List;
6 | import java.util.stream.Collectors;
7 |
8 | /**
9 | * @author biezhi
10 | * @date 2018/2/11
11 | */
12 | public class Java8 {
13 |
14 | public static void main(String[] args) {
15 | List projects = Project.buildData();
16 | List names = projects.stream()
17 | .filter(p -> {
18 | System.out.println(p.getName());
19 | return p.getStars() > 1000;
20 | })
21 | .map(p -> {
22 | System.out.println(p.getName());
23 | return p.getName();
24 | })
25 | .limit(3)
26 | .collect(Collectors.toList());
27 | System.out.println(names);
28 |
29 | names.stream().forEach(name-> System.out.println(name));
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson2/Example1.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.stream.lesson2;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 | import java.util.stream.Stream;
6 |
7 | /**
8 | * 创建流
9 | *
10 | * Stream.of
11 | * Arrays.stream
12 | * collection.stream
13 | * Files.lines
14 | * Stream.iterate
15 | *
16 | * @author biezhi
17 | * @date 2018/2/12
18 | */
19 | public class Example1 {
20 |
21 | public static void main(String[] args) {
22 | List list = Arrays.asList("hello", "world");
23 | Stream stream = list.stream();
24 |
25 | Stream stringStream = Arrays.stream(new String[]{"hello", "world"});
26 |
27 | Stream stream1 = Stream.of("hello", "world");
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson2/Example2.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.stream.lesson2;
2 |
3 | import io.github.biezhi.java8.stream.Project;
4 |
5 | import java.util.List;
6 | import java.util.stream.Collectors;
7 | import java.util.stream.Stream;
8 |
9 | /**
10 | * 筛选元素
11 | *
12 | * filter 使用
13 | * distinct 使用
14 | * limit 使用
15 | * skip 使用
16 | *
17 | * @author biezhi
18 | * @date 2018/2/12
19 | */
20 | public class Example2 {
21 |
22 | public static void main(String[] args) {
23 | List projects = Project.buildData();
24 |
25 | List collect = projects.stream()
26 | .filter(project -> project.getStars() > 1000)
27 | .collect(Collectors.toList());
28 |
29 | // distinct
30 | Stream numbers = Stream.of(1, 2, 3, 3, 2, 4);
31 | numbers.distinct().limit(3).forEach(n -> System.out.println(n));
32 |
33 | System.out.println("===================");
34 | Stream.of(1, 2, 3, 3, 2, 4).skip(4).forEach(n -> System.out.println(n));
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson2/Example3.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.stream.lesson2;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 | import java.util.stream.Collectors;
6 |
7 | /**
8 | * 映射
9 | *
10 | * map 使用
11 | *
12 | * @author biezhi
13 | * @date 2018/2/12
14 | */
15 | public class Example3 {
16 |
17 | public static void main(String[] args) {
18 | List words = Arrays.asList("Java 8", "Lambdas", "In", "Action");
19 |
20 | words.stream()
21 | .map(word -> word.length())
22 | .collect(Collectors.toList())
23 | .forEach(i -> System.out.println(i));
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/java8-stream/src/main/java/io/github/biezhi/java8/stream/lesson2/Example4.java:
--------------------------------------------------------------------------------
1 | package io.github.biezhi.java8.stream.lesson2;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 | import java.util.stream.Collectors;
6 |
7 | /**
8 | * 扁平流 flatMap
9 | *