Upload
vyacheslav-lapin
View
202
Download
1
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
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