35
1 CONFIDENTIAL Senior developer 10+ years experience in IT 7+ Java-development experience 5+ trainer experience 3+ system analysis Interests: Messaging Functional programming (Clojure, Scala) About author

ITSubbotik - как скрестить ежа с ужом или подводные камни внедрения функционального программирования для

Embed Size (px)

Citation preview

1CONFIDENTIAL

Senior developer

10+ years experience in IT

• 7+ Java-development experience

• 5+ trainer experience

• 3+ system analysis

Interests:

• Messaging

• Functional programming (Clojure,

Scala)

About author

2CONFIDENTIAL

• Parallel Streams can actually slow you down

• The flip-side of Lambda expressions

• Default Methods are distracting

• Checked Exceptions

• Field Access

• Stream API support

• CriptoPro`blem…

• NIO-2 WatchService

• Generics in ENUM`s

AGENDA

3CONFIDENTIAL

Parallel Streams can actually slow you down

• Java 8 brings the promise of parallelism as one of the most anticipated new features. The

.parallelStream() method implements this on collections and streams. It breaks them into

subproblems which then run on separate threads for processing, these can go to different cores and

then get combined when they’re done. This all happens under the hood using the fork/join

framework.

• Ok, sounds cool, it must speed up operations on large data sets in multi-core environments, right?

Stream API in Enterprise Java - Problems

4CONFIDENTIAL

Parallel Streams can actually slow you down

• Let`s test it:

• To sort an array using multiple cores all you have to do is –

– Arrays.parallelSort(numbers);

• To group a collection into different groups based on a specific criteria (e.g. prime and non-prime

numbers)

– Map<Boolean, List> groupByPrimary = numbers.parallelStream()

.collect(Collectors.groupingBy(s -> Utility.isPrime(s)));

• 3 . To filter out values all you have do is –

– Integer[] prims = numbers.parallelStream().filter(s -> Utility.isPrime(s))

.toArray();

Stream API in Enterprise Java - Problems

5CONFIDENTIAL

Parallel Streams can actually slow you down

• https://github.com/takipi/java-8-parallelism-benchmarks

Stream API in Enterprise Java - Problems

6CONFIDENTIAL

Parallel Streams can actually slow you down

• The results were not surprising:

• Quicksort is now 4.7X times faster.

• Grouping is now 5X times faster.

• Filtering is now 5.5X times faster.

• A happy ending? Unfortunately not.

• So what happens under load?

• So far things have been quite peachy, the reason being that there’s little contention between

threads for CPU cycles. That’s an ideal situation, but unfortunately, one that doesn’t happen a

lot in real life. To simulate a scenario which is more on par with what you’d normally see in a

real-world environment I set up a second test. This test runs the same set of algorithms, but

this time executes them on ten concurrent threads to simulate processing ten concurrent

requests performed by a server when it’s under pressure. Each of those requests will then be

handled either sequentially using a traditional approach, or the new Java 8 APIs.

Stream API in Enterprise Java - Problems

7CONFIDENTIAL

Parallel Streams can actually slow you down

• The results:

• Sorting in now only 20% faster – a 23X decline.

• Filtering is now only 20% faster – a 25X decline.

• Grouping is now 15% slower.

Stream API in Enterprise Java - Problems

8CONFIDENTIAL

Parallel Streams can actually slow you down

• https://github.com/takipi/java-8-parallelism-benchmarks

• http://blog.takipi.com/new-parallelism-apis-in-java-8-behind-the-glitz-and-glamour/

• Diagnosis

• Parallelism with all its benefits also brings in additional types of problems to consider.

• When already acting in a multi-threaded environment, keep this in mind and get yourself

familiar with what’s going on behind the scenes.

Stream API in Enterprise Java - Problems

9CONFIDENTIAL

The flip-side of Lambda expressions - 1

• http://blog.takipi.com/the-dark-side-of-lambda-expressions-in-java-8/

• Let’s say I rise up in the morning and want to iterate over a list of world cup teams and map

their lengths:

• List<Boolean> lengths = new ArrayList<>();

for (String country : Arrays.asList(args)) {

lengths.add(check(country));

}

• Now let’s get functional with a nice lambda:

• Stream lengths = countries.stream().map(countries -> check(country));

• …and what if check method throws an Exception?

Stream API in Enterprise Java - Problems

10CONFIDENTIAL

The flip-side of Lambda expressions - 1

• In that case:

• List<Boolean> lengths = new ArrayList<>();

for (String country : Arrays.asList(args)) {

lengths.add(check(country));

}

• , we`ve got:

• at LmbdaMain.check(LmbdaMain.java:19)

at LmbdaMain.main(LmbdaMain.java:34)

Stream API in Enterprise Java - Problems

11CONFIDENTIAL

The flip-side of Lambda expressions - 1

• In that case:

• Stream lengths = countries.stream().map(countries -> check(country));

• , we`ve got:

• at LmbdaMain.check(LmbdaMain.java:19)

at LmbdaMain.lambda$0(LmbdaMain.java:37)

at LmbdaMain$$Lambda$1/821270929.apply(Unknown Source)

at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)

at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)

at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512)

at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502)

at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)

at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)

at java.util.stream.LongPipeline.reduce(LongPipeline.java:438)

at java.util.stream.LongPipeline.sum(LongPipeline.java:396)

at java.util.stream.ReferencePipeline.count(ReferencePipeline.java:526)

at LmbdaMain.main(LmbdaMain.java:39)

Stream API in Enterprise Java - Problems

12CONFIDENTIAL

The flip-side of Lambda expressions - 1

• In that case:

• ScriptEngineManager manager = new ScriptEngineManager();

ScriptEngine engine = manager.getEngineByName("nashorn");

String js = "var map = Array.prototype.map \n";

• js += "var a = map.call(names, function(name) { return

Java.type(\"LmbdaMain\").check(name) }) \n";

js += "print(a)";

engine.eval(js);

Stream API in Enterprise Java - Problems

13CONFIDENTIAL

The flip-side of Lambda expressions - 1

• , we`ve got (1):

• LmbdaMain [Java Application]

• LmbdaMain at localhost:51287

• Thread [main] (Suspended (breakpoint at line 16 in LmbdaMain))

• LmbdaMain.wrap(String) line: 16

• 1525037790.invokeStatic_L_I(Object, Object) line: not available

• 1150538133.invokeSpecial_LL_I(Object, Object, Object) line: not available

• 538592647.invoke_LL_I(MethodHandle, Object[]) line: not available

• 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147

• LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625

• LambdaForm.interpretWithArguments(Object...) line: 604

• 2150540.interpret_I(MethodHandle, Object, Object) line: not available

• 538592647.invoke_LL_I(MethodHandle, Object[]) line: not available

• 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147

• LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625

• LambdaForm.interpretWithArguments(Object...) line: 604

• 92150540.interpret_I(MethodHandle, Object, Object) line: not available

• 38592647.invoke_LL_I(MethodHandle, Object[]) line: not available

• 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147

• LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625

Stream API in Enterprise Java - Problems

14CONFIDENTIAL

The flip-side of Lambda expressions - 1

• , we`ve got (2):

• LambdaForm.interpretWithArguments(Object...) line: 604

• 731260860.interpret_L(MethodHandle, Object, Object) line: not available

• LambdaForm$NamedFunction.invoke_LL_L(MethodHandle, Object[]) line: 1108

• 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147

• LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625

• LambdaForm.interpretWithArguments(Object...) line: 604

• 2619171.interpret_L(MethodHandle, Object, Object, Object) line: not available

• 1597655940.invokeSpecial_LLLL_L(Object, Object, Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invoke_LLLL_L(MethodHandle, Object[]) line: 1118

• 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147

• LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625

• LambdaForm.interpretWithArguments(Object...) line: 604

• 2619171.interpret_L(MethodHandle, Object, Object, Object) line: not available

• 1353530305.linkToCallSite(Object, Object, Object, Object) line: not available

• Script$\^eval\_._L3(ScriptFunction, Object, Object) line: 3

• 1596000437.invokeStatic_LLL_L(Object, Object, Object, Object) line: not available

• 1597655940.invokeSpecial_LLLL_L(Object, Object, Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invoke_LLLL_L(MethodHandle, Object[]) line: 1118

• 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147

Stream API in Enterprise Java - Problems

15CONFIDENTIAL

The flip-side of Lambda expressions - 1

• , we`ve got (3):

• LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625

• LambdaForm.interpretWithArguments(Object...) line: 604

• 484673893.interpret_L(MethodHandle, Object, Object, Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invoke_LLLLL_L(MethodHandle, Object[]) line: 1123

• 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147

• LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625

• LambdaForm.interpretWithArguments(Object...) line: 604

• 282496973.interpret_L(MethodHandle, Object, Object, Object, long, Object) line: not available

• 93508253.invokeSpecial_LLLLJL_L(Object, Object, Object, Object, Object, long, Object) line: not available

• 1850777594.invoke_LLLLJL_L(MethodHandle, Object[]) line: not available

• 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147

• LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625

• LambdaForm.interpretWithArguments(Object...) line: 604

• 282496973.interpret_L(MethodHandle, Object, Object, Object, long, Object) line: not available

• 293508253.invokeSpecial_LLLLJL_L(Object, Object, Object, Object, Object, long, Object) line: not available

• 1850777594.invoke_LLLLJL_L(MethodHandle, Object[]) line: not available

• 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147

• LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625

• LambdaForm.interpretWithArguments(Object...) line: 604

Stream API in Enterprise Java - Problems

16CONFIDENTIAL

The flip-side of Lambda expressions - 1

• , we`ve got (4):

• 1840903588.interpret_L(MethodHandle, Object, Object, Object, Object, long, Object) line: not available

• 2063763486.reinvoke(Object, Object, Object, Object, Object, long, Object) line: not available

• 850777594.invoke_LLLLJL_L(MethodHandle, Object[]) line: not available

• 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147

• LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625

• LambdaForm.interpretWithArguments(Object...) line: 604

• 82496973.interpret_L(MethodHandle, Object, Object, Object, long, Object) line: not available

• 220309324.invokeExact_MT(Object, Object, Object, Object, long, Object, Object) line: not available

• NativeArray$10.forEach(Object, long) line: 1304

• NativeArray$10(IteratorAction).apply() line: 124

• NativeArray.map(Object, Object, Object) line: 1315

• 1596000437.invokeStatic_LLL_L(Object, Object, Object, Object) line: not available

• 504858437.invokeExact_MT(Object, Object, Object, Object, Object) line: not available

• FinalScriptFunctionData(ScriptFunctionData).invoke(ScriptFunction, Object, Object...) line: 522

• ScriptFunctionImpl(ScriptFunction).invoke(Object, Object...) line: 207

• ScriptRuntime.apply(ScriptFunction, Object, Object...) line: 378

• NativeFunction.call(Object, Object...) line: 161

• 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available

• 1740189450.invokeSpecial_LLL_L(Object, Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invoke_LLL_L(MethodHandle, Object[]) line: 1113

• 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available

Stream API in Enterprise Java - Problems

17CONFIDENTIAL

The flip-side of Lambda expressions - 1

• , we`ve got (5):

• LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147

• LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625

• LambdaForm.interpretWithArguments(Object...) line: 604

• 2619171.interpret_L(MethodHandle, Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invoke_LLL_L(MethodHandle, Object[]) line: 1113

• 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147

• LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625

• LambdaForm.interpretWithArguments(Object...) line: 604

• 323326911.interpret_L(MethodHandle, Object, Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invoke_LLLL_L(MethodHandle, Object[]) line: 1118

• 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147

• LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625

• LambdaForm.interpretWithArguments(Object...) line: 604

• 323326911.interpret_L(MethodHandle, Object, Object, Object, Object) line: not available

• 263793464.invokeSpecial_LLLLL_L(Object, Object, Object, Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invoke_LLLLL_L(MethodHandle, Object[]) line: 1123

• 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147

• LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625

• LambdaForm.interpretWithArguments(Object...) line: 604

Stream API in Enterprise Java - Problems

18CONFIDENTIAL

The flip-side of Lambda expressions - 1

• , we`ve got (6):

• 1484673893.interpret_L(MethodHandle, Object, Object, Object, Object, Object) line: not available

• 587003819.invokeSpecial_LLLLLL_L(Object, Object, Object, Object, Object, Object, Object) line: not available

• 811301908.invoke_LLLLLL_L(MethodHandle, Object[]) line: not available

• 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147

• LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625

• LambdaForm.interpretWithArguments(Object...) line: 604

• 484673893.interpret_L(MethodHandle, Object, Object, Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invoke_LLLLL_L(MethodHandle, Object[]) line: 1123

• 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available

• LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147

• LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625

• LambdaForm.interpretWithArguments(Object...) line: 604

• 323326911.interpret_L(MethodHandle, Object, Object, Object, Object) line: not available

• 2129144075.linkToCallSite(Object, Object, Object, Object, Object) line: not available

• Script$\^eval\_.runScript(ScriptFunction, Object) line: 3

• 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available

• 1709804316.invokeExact_MT(Object, Object, Object, Object) line: not available

• FinalScriptFunctionData(ScriptFunctionData).invoke(ScriptFunction, Object, Object...) line: 498

• ScriptFunctionImpl(ScriptFunction).invoke(Object, Object...) line: 207

• ScriptRuntime.apply(ScriptFunction, Object, Object...) line: 378

• NashornScriptEngine.evalImpl(ScriptFunction, ScriptContext, ScriptObject) line: 544

Stream API in Enterprise Java - Problems

19CONFIDENTIAL

The flip-side of Lambda expressions - 1

• , we`ve got (7):

• NashornScriptEngine.evalImpl(ScriptFunction, ScriptContext) line: 526

• NashornScriptEngine.evalImpl(Source, ScriptContext) line: 522

• NashornScriptEngine.eval(String, ScriptContext) line: 193

• NashornScriptEngine(AbstractScriptEngine).eval(String) line: 264

• LmbdaMain.main(String[]) line: 44

Stream API in Enterprise Java - Problems

20CONFIDENTIAL

The flip-side of Lambda expressions - 1

• Diagnosis

• Just stay aware of this, the traces might be a pain from time to time, but it will not keep us

away from them precious lambdas.

Stream API in Enterprise Java - Problems

21CONFIDENTIAL

The flip-side of Lambda expressions – 2

• Overloading gets even worse:

• static <T> T run(Callable<T> c) throws Exception {

return c.call();

}

static <T> T run(Supplier<T> s) throws Exception {

return s.get();

}

• So, we can`t call one of it this way:

• public static void main(String[] args)

throws Exception {

run(() -> null);

// ^^^^^^^^^^ ambiguous method call!

}

• (so, it`s the «static import» and method-pointer`s problem too!)

Stream API in Enterprise Java - Problems

22CONFIDENTIAL

The flip-side of Lambda expressions – 3

• http://blog.jooq.org/2014/04/04/java-8-friday-the-dark-side-of-java-8/

• Not all keywords are supported on default methods:

• They cannot be made final (so, static final too)

• They cannot be made synchronized

• The default keyword:

// Interfaces are always abstract

public /* abstract */ interface NoTrait {

// Abstract methods have no bodies - the abstract keyword is optional

/* abstract */ void run1();

// Concrete methods have bodies - the default keyword is mandatory

default void run2() {}

}

// Classes can optionally be abstract

public abstract class NoInterface {

// Abstract methods have no bodies - the abstract keyword is mandatory

abstract void run1();

// Concrete methods have bodies - the default keyword mustn't be used

void run2() {}

}

Stream API in Enterprise Java - Problems

23CONFIDENTIAL

Default Methods are distracting

http://zeroturnaround.com/rebellabs/how-your-addiction-to-java-8-default-

methods-may-make-pandas-sad-and-your-teammates-angry/

public interface TimeClient {

// ...

static ZoneId getZoneId (String zoneString) {

try {

return ZoneId.of(zoneString);

} catch (DateTimeException e) {

System.err.println("Invalid time zone: " + zoneString + "; using default time zone instead.");

return ZoneId.systemDefault();

}

}

default ZonedDateTime getZonedDateTime(String zoneString) {

return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));

}

}

Diagnosis:

When you hold a hammer everything looks like a nail, keep in mind to stick to their original use case, evolution of

an existing interface when a refactor to introduce a new abstract class doesn’t make sense.

Stream API in Enterprise Java - Problems

24CONFIDENTIAL

Checked Exceptions

• lambda expressions can't declare its throws-clause and lambda body can't throw checked exception

such as IOException

Stream API in Enterprise Java - Problems

25CONFIDENTIAL

Checked Exceptions

• lambda expressions can't declare its throws-clause and lambda body can't throw checked exception

such as IOException

• What if we want to make code like this compile:

• public List<Class> getClasses() throws ClassNotFoundException {

return Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String")

.map(className -> Class.forName(className))

.collect(Collectors.toList());

}

• This code does not compile, since the Class.forName() method above throws

ClassNotFoundException, which is checked.

Stream API in Enterprise Java - Problems

26CONFIDENTIAL

Checked Exceptions

• Real case:

• public List<Class> getClasses() throws ClassNotFoundException {

return Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String")

.map(className -> {

try {

return Class.forName(className);

} catch (ClassNotFoundException e)

return null;}})

.filter(aClass -> aClass != null)

.collect(Collectors.toList());

}

Stream API in Enterprise Java - Problems

27CONFIDENTIAL

Field Access

• class Person {

public String name;

public String getName() { return name; }

}

• If we can write this code:

• List<Person> persons;

persons.stream().map(Person::getName).collect(Collectors.toList());

persons.stream().map(p -> p.name).collect(Collectors.toList());

• Why can`t we write something like this?

• persons.stream().map(Person::name).collect(Collectors.toList());

Stream API in Enterprise Java - Problems

28CONFIDENTIAL

Stream API support

• Not present for:

• XPath,

• Serialization (Java, XML, JSON, others),

• Messaging (RebbitMQ, ZeroMQ, Kafka),

• NIO2

• JDBC and JPA

• etc.

Stream API in Enterprise Java - Problems

29CONFIDENTIAL

CriptoPro`blem…

• КриптоПро JCP функционирует в следующем окружении:

• виртуальной машина, удовлетворяющая спецификации Sun Java 2 ™ Virtual Machine;

• требуется Java 2 Runtime Environment версии 1.4.2, 1.5.0 для версии JCP 1.0.46,

Java 6 и выше для 1.0.54 (для этой версии - Java до 1.7.0_25) и 2.x;

Stream API in Enterprise Java - Problems

30CONFIDENTIAL

CriptoPro`blem…

• КриптоПро JCP функционирует в следующем окружении:

• виртуальной машина, удовлетворяющая спецификации Sun Java 2 ™ Virtual Machine;

• требуется Java 2 Runtime Environment версии 1.4.2, 1.5.0 для версии JCP 1.0.46,

Java 6 и выше для 1.0.54 (для этой версии - Java до 1.7.0_25) и 2.x;

Stream API in Enterprise Java - Problems

31CONFIDENTIAL

NIO-2 WatchService

Path path = Paths.get("C:\\Temp\\Users");

try (WatchService watchService = FileSystems.getDefault().newWatchService()) {

WatchKey watchKey = path.register(watchService, ENTRY_CREATE, ENTRY_DELETE,

NTRY_MODIFY);

while (true)

try {

System.out.print("Wating for event... ");

for (WatchEvent<?> event : watchService.take().pollEvents())

System.out.println(new Date().toString() + " " + event.kind() + " " +

event.context());

watchKey.reset();

} catch (InterruptedException e) {

Thread.currentThread().interrupt();

}

}

Stream API in Enterprise Java - Problems

32CONFIDENTIAL

NIO-2 WatchService

Printed:

Wating for event... Wed Jun 25 21:05:38 MSK 2014 ENTRY_CREATE 1.txt

Wating for event... Wed Jun 25 21:05:38 MSK 2014 ENTRY_MODIFY 1.txt

Wed Jun 25 21:05:38 MSK 2014 ENTRY_CREATE 2.txt

Wed Jun 25 21:05:38 MSK 2014 ENTRY_MODIFY 2.txt

Wed Jun 25 21:05:38 MSK 2014 ENTRY_CREATE 3.txt

Wed Jun 25 21:05:38 MSK 2014 ENTRY_MODIFY 3.txt

Wed Jun 25 21:05:38 MSK 2014 ENTRY_CREATE 4.txt

Wed Jun 25 21:05:38 MSK 2014 ENTRY_MODIFY 4.txt

Wating for event... Wed Jun 25 21:06:24 MSK 2014 ENTRY_MODIFY 2.txt

Wating for event... Wed Jun 25 21:06:24 MSK 2014 ENTRY_MODIFY 2.txt

Wating for event... Wed Jun 25 21:08:53 MSK 2014 ENTRY_MODIFY 3.txt

Wating for event... Wed Jun 25 21:08:53 MSK 2014 ENTRY_MODIFY 3.txt

Wating for event... Wed Jun 25 21:08:53 MSK 2014 ENTRY_MODIFY 3.txt

Wating for event...

Stream API in Enterprise Java - Problems

33CONFIDENTIAL

NIO-2 WatchService

Stream API in Enterprise Java - Problems

34CONFIDENTIAL

Generics in ENUM`s

• public enum XPathFilter<T> {

LINKS_FILTER<String>("//div[@class='reports_file']/a", x -> ((XdmItem) x).getStringValue()),

ADJACENT_FILTER<Integer>("...", x -> {/*...*/} );

private String xPath;

private Function<XdmValue, T> function;

XPathFilter(String xPath, Function<XdmValue, T> function) {

this.xPath = xPath;

this.function = function;

}

}

Stream API in Enterprise Java - Problems

35CONFIDENTIAL

Thank you!

Questions?

VYACHESLAV LAPIN