1+ package pl .mperor .lab .java ;
2+
3+
4+ import org .junit .jupiter .api .Assertions ;
5+ import org .junit .jupiter .api .Test ;
6+ import pl .mperor .lab .TestUtils ;
7+
8+ import java .lang .reflect .Method ;
9+ import java .lang .reflect .Modifier ;
10+ import java .time .*;
11+ import java .util .*;
12+ import java .util .function .*;
13+ import java .util .stream .Collectors ;
14+ import java .util .stream .IntStream ;
15+ import java .util .stream .Stream ;
16+
17+ /**
18+ * Java 1.8 (March 2014)
19+ */
20+ public class Java8 {
21+
22+ @ Test
23+ public void testLambdaExpression () {
24+ var out = TestUtils .setTempSystemOut ();
25+ Runnable anonymousInnerClass = new Runnable () {
26+ @ Override
27+ public void run () {
28+ System .out .println ("Hello World from anonymous inner class!" );
29+ }
30+ };
31+ Runnable lambdaExpression = () -> System .out .println ("Hello World from Lambda!" );
32+
33+ anonymousInnerClass .run ();
34+ lambdaExpression .run ();
35+
36+ Assertions .assertEquals ("Hello World from anonymous inner class!" , out .lines ().getFirst ());
37+ Assertions .assertEquals ("Hello World from Lambda!" , out .lines ().getSecond ());
38+
39+ Assertions .assertInstanceOf (Runnable .class , anonymousInnerClass );
40+ Assertions .assertInstanceOf (Runnable .class , lambdaExpression );
41+ TestUtils .resetSystemOut ();
42+ }
43+
44+ @ Test
45+ public void testCoreFunctionalInterfaces () {
46+ Predicate <?> nullValidator = Objects ::isNull ;
47+ Assertions .assertTrue (nullValidator .test (null ));
48+
49+ var out = TestUtils .setTempSystemOut ();
50+ Consumer <String > systemPrinter = System .out ::print ;
51+ systemPrinter .accept ("printed" );
52+ Assertions .assertEquals ("printed" , out .all ());
53+ TestUtils .resetSystemOut ();
54+
55+ Supplier <Double > randomGenerator = Math ::random ;
56+ Double random = randomGenerator .get ();
57+ Assertions .assertTrue (random >= 0.0 && random < 1.0 );
58+
59+ UnaryOperator <Integer > absoluteUpdater = Math ::abs ;
60+ Assertions .assertEquals (1 , absoluteUpdater .apply (-1 ));
61+
62+ Function <String , Integer > numberParser = Integer ::parseInt ;
63+ Assertions .assertEquals (1 , numberParser .apply ("1" ));
64+ }
65+
66+ @ Test
67+ public void testCustomFunctionalInterface () {
68+ Testable testable = () -> {
69+ };
70+ testable .test ();
71+ // same as Runnable runnable = () -> {};
72+
73+ assertFunctionalInterface (Testable .class );
74+ }
75+
76+ private static void assertFunctionalInterface (Class <?> clazz ) {
77+ if (!clazz .isInterface ()) {
78+ Assertions .fail ("Clazz is not an interface!" );
79+ }
80+
81+ long abstractMethodCount = Arrays .stream (clazz .getMethods ())
82+ .map (Method ::getModifiers )
83+ .filter (Modifier ::isAbstract )
84+ .count ();
85+
86+ Assertions .assertTrue (clazz .isAnnotationPresent (FunctionalInterface .class ) || 1 == abstractMethodCount ,
87+ "Functional interface should contain exactly one abstract method, but @FunctionalInterface is optional!" );
88+ }
89+
90+ @ FunctionalInterface
91+ public interface Testable {
92+ void test ();
93+ }
94+
95+ @ Test
96+ public void testDefaultAndStaticMethodsInInterface () throws NoSuchMethodException {
97+ Tester tester = () -> new Testable []{
98+ () -> System .out .println ("First test" ),
99+ () -> System .out .println ("Second test" ),
100+ };
101+ var out = TestUtils .setTempSystemOut ();
102+ tester .run ();
103+ Assertions .assertEquals ("First test" , out .lines ().getFirst ());
104+ Assertions .assertEquals ("Second test" , out .lines ().getSecond ());
105+ TestUtils .resetSystemOut ();
106+
107+ Method defaultMethod = Tester .class .getMethod ("run" );
108+ Assertions .assertTrue (defaultMethod .isDefault ());
109+
110+ Method staticMethod = Tester .class .getMethod ("checkAll" , Testable [].class );
111+ Assertions .assertTrue (Modifier .isStatic (staticMethod .getModifiers ()));
112+
113+ assertFunctionalInterface (Tester .class );
114+ }
115+
116+ public interface Tester {
117+
118+ Testable [] getTests ();
119+
120+ default void run () {
121+ checkAll (getTests ());
122+ }
123+
124+ static void checkAll (Testable ... testable ) {
125+ Arrays .stream (testable ).forEach (Testable ::test );
126+ }
127+ }
128+
129+ @ Test
130+ public void testOptional () {
131+ Optional <String > empty = Optional .empty ();
132+ Assertions .assertTrue (empty .isEmpty ());
133+ Assertions .assertThrows (NoSuchElementException .class , () -> empty .get ());
134+
135+ Optional <String > filled = Optional .of ("Java 8" );
136+ Assertions .assertTrue (filled .isPresent ());
137+ Assertions .assertEquals ("Java 8" , filled .get ());
138+ filled .ifPresent (content -> Assertions .assertEquals ("Java 8" , content ));
139+ }
140+
141+ @ Test
142+ public void testMethodReferences () {
143+ Runnable staticMethod = Reference ::staticMethod ;
144+ staticMethod .run ();
145+
146+ Reference instance = new Reference ();
147+ Runnable particularObjectInstanceMethod = instance ::instanceMethod ;
148+ particularObjectInstanceMethod .run ();
149+
150+ Supplier <Reference > constructorMethod = Reference ::new ;
151+ Assertions .assertNotNull (constructorMethod .get ());
152+
153+ Consumer <Reference > arbitraryObjectInstanceMethod = Reference ::instanceMethod ;
154+ arbitraryObjectInstanceMethod .accept (new Reference ());
155+ }
156+
157+ public class Reference {
158+
159+ public void instanceMethod () {
160+ }
161+
162+ public static void staticMethod () {
163+ }
164+ }
165+
166+ @ Test
167+ public void testStreamsAPI () {
168+ // Stream Creation
169+ Assertions .assertInstanceOf (Stream .class , List .of (1 , 2 , 3 ).stream ());
170+ Assertions .assertInstanceOf (IntStream .class , Arrays .stream (new int []{1 , 2 , 3 }));
171+ Assertions .assertInstanceOf (Stream .class , Stream .of (1 , 2 , 3 ));
172+
173+ // Intermediate Operations
174+ Stream <String > intermediateOperationPipeline = List .of ("c" , "b" , "a" , "" ).stream ()
175+ .filter (s -> s .matches ("^\\ w$" ))
176+ .map (String ::toUpperCase )
177+ .sorted ();
178+ Assertions .assertInstanceOf (Stream .class , intermediateOperationPipeline );
179+ Assertions .assertEquals ("ABC" , intermediateOperationPipeline .collect (Collectors .joining ()));
180+ IllegalStateException exception = Assertions .assertThrows (IllegalStateException .class , intermediateOperationPipeline ::count );
181+ Assertions .assertEquals ("stream has already been operated upon or closed" , exception .getMessage ());
182+
183+ // Terminal Operations
184+ Assertions .assertEquals (3 , IntStream .rangeClosed (1 , 3 ).count ());
185+ Assertions .assertEquals (6 , IntStream .rangeClosed (1 , 3 ).sum ());
186+ Assertions .assertEquals (6 , IntStream .rangeClosed (1 , 3 ).reduce (1 , (a , b ) -> a * b ));
187+ Assertions .assertEquals (List .of (1 , 2 , 3 ), IntStream .rangeClosed (1 , 3 ).boxed ().collect (Collectors .toList ()));
188+ Assertions .assertEquals (OptionalInt .of (3 ), IntStream .rangeClosed (1 , 3 ).max ());
189+ }
190+
191+ @ Test
192+ public void testNewDateAndTimeAPI () {
193+ // same as DateTimeFormatter.ISO_LOCAL_DATE.parse(...)
194+ LocalDate releaseJava8Date = LocalDate .parse ("2014-03-18" );
195+ Assertions .assertEquals (LocalDate .of (2014 , Month .MARCH , 18 ), releaseJava8Date );
196+
197+ LocalTime noonTime = LocalTime .of (12 , 0 , 0 );
198+ Assertions .assertEquals (LocalTime .NOON , noonTime );
199+
200+ // same as DateTimeFormatter.ISO_LOCAL_DATE_TIME.parse(...)
201+ LocalDateTime twoThousand = LocalDateTime .parse ("2000-01-01T00:00:00" );
202+ Assertions .assertEquals (LocalDateTime .of (2000 , 1 , 1 , 0 , 0 , 0 ), twoThousand );
203+
204+ Period betweenJava1And8 = Period .between (LocalDate .of (1996 , Month .JANUARY , 23 ), LocalDate .of (2014 , Month .MARCH , 8 ));
205+ Assertions .assertEquals (18 , betweenJava1And8 .getYears ());
206+
207+ Duration betweenMidnightAndNoon = Duration .between (LocalTime .MIDNIGHT , LocalTime .NOON );
208+ Assertions .assertEquals (12 , betweenMidnightAndNoon .toHours ());
209+
210+ Instant initialInstant = Instant .ofEpochSecond (0 );
211+ Assertions .assertEquals ("1970-01-01T00:00:00Z" , initialInstant .toString ());
212+ Assertions .assertEquals (60 , initialInstant .plusSeconds (60 ).getEpochSecond ());
213+ }
214+
215+ }
0 commit comments