• No results found

Learn How to Implement Java Sequential SearchStreamGang Hook Methods

N/A
N/A
Protected

Academic year: 2021

Share "Learn How to Implement Java Sequential SearchStreamGang Hook Methods"

Copied!
36
0
0

Loading.... (view fulltext now)

Full text

(1)

Learn How to Implement Java Sequential

SearchStreamGang Hook Methods

Douglas C. Schmidt

[email protected]

www.dre.vanderbilt.edu/~schmidt

Professor of Computer Science

Institute for Software

Integrated Systems

Vanderbilt University

Nashville, Tennessee, USA

(2)

2

Learning Objectives in this Part of the Lesson

Know how to apply sequential streams to the SearchStreamGang program

Understand the SearchStreamGang process

Stream() & processInput() hook methods

Starting SearchStreamGangTest

PARALLEL_SPLITERATOR executed in 409 msecs

COMPLETABLE_FUTURES_INPUTS executed in 426 msecs COMPLETABLE_FUTURES_PHASES executed in 427 msecs PARALLEL_STREAMS executed in 437 msecs

PARALLEL_STREAM_PHASES executed in 440 msecs RXJAVA_PHASES executed in 485 msecs

PARALLEL_STREAM_INPUTS executed in 802 msecs RXJAVA_INPUTS executed in 866 msecs

SEQUENTIAL_LOOPS executed in 1638 msecs

SEQUENTIAL_STREAM executed in 1958 msecs

Ending SearchStreamGangTest map(phrase -> searchForPhrase(…)) filter(not(SearchResults::isEmpty)) collect(toList()) 45,000+ phrases Search Phrases stream()

(3)

3

Implementing

processStream() as a

Sequential Stream

(4)

4

processStream

() sequentially searches for phrases in lists of input “strings”

Implementing processStream() as a Sequential Stream

… Stream<List <SearchResults>> Stream <CharSequence> List<List <SearchResults>> … List <CharSequence> … map(this::processInput) collect(toList())

Input Strings to Search

stream() Complete works of Shakespeare

(5)

5

processStream

() sequentially searches for phrases in lists of input “strings”

protected List<List<SearchResults>> processStream() { List<CharSequence> inputList = getInput();

return inputList .stream()

.map(this::processInput) .collect(toList());

}

(6)

6

processStream

() sequentially searches for phrases in lists of input “strings”

protected List<List<SearchResults>> processStream() {

List<CharSequence> inputList = getInput();

return inputList .stream()

.map(this::processInput) .collect(toList());

}

Implementing processStream() as a Sequential Stream

Get list of strings containing all works of Shakespeare

(7)

7

processStream

() sequentially searches for phrases in lists of input “strings”

protected List<List<SearchResults>> processStream() {

List<CharSequence> inputList = getInput();

return inputList .stream()

.map(this::processInput) .collect(toList());

}

Implementing processStream() as a Sequential Stream

(8)

8

processStream

() sequentially searches for phrases in lists of input “strings”

protected List<List<SearchResults>> processStream() {

List<CharSequence> inputList = getInput();

return inputList .stream()

.map(this::processInput) .collect(toList());

}

Implementing processStream() as a Sequential Stream

CharSequence optimizes subSequence() to avoid memory copies (cf. String substring())

(9)

9

processStream

() sequentially searches for phrases in lists of input “strings”

protected List<List<SearchResults>> processStream() { List<CharSequence> inputList = getInput();

return inputList .stream()

.map(this::processInput) .collect(toList());

}

Implementing processStream() as a Sequential Stream

Returns a list of lists of search results denoting how many times a search phrase appeared in each input string

(10)

10

See “

Java Sequential SearchStreamGang Example: Implementing printPhrases()

processStream

() sequentially searches for phrases in lists of input “strings”

protected List<List<SearchResults>> processStream() { List<CharSequence> inputList = getInput();

return inputList .stream()

.map(this::processInput) .collect(toList());

}

Implementing processStream() as a Sequential Stream

We’ll later show how flatMap() “flattens” List<List

(11)

11

processStream

() sequentially searches for phrases in lists of input “strings”

protected List<List<SearchResults>> processStream() { List<CharSequence> inputList = getInput();

return inputList .stream()

.map(this::processInput) .collect(toList());

}

Implementing processStream() as a Sequential Stream

Stores # of times a phrase appeared in an input string

(12)

12

processStream

() sequentially searches for phrases in lists of input “strings”

protected List<List<SearchResults>> processStream() { List<CharSequence> inputList = getInput();

return inputList

.stream()

.map(this::processInput)

.collect(toList());

}

Implementing processStream() as a Sequential Stream

processStream() is implemented via a sequential stream pipeline

(13)

13

processStream

() sequentially searches for phrases in lists of input “strings”

protected List<List<SearchResults>> processStream() { List<CharSequence> inputList = getInput();

return inputList

.stream()

.map(this::processInput) .collect(toList());

}

Implementing processStream() as a Sequential Stream

This factory method converts the input list into a stream

(14)

14

processStream

() sequentially searches for phrases in lists of input “strings”

protected List<List<SearchResults>> processStream() { List<CharSequence> inputList = getInput();

return inputList .stream()

.map(this::processInput)

.collect(toList()); }

Implementing processStream() as a Sequential Stream

(15)

15

processStream

() sequentially searches for phrases in lists of input “strings”

protected List<List<SearchResults>> processStream() { List<CharSequence> inputList = getInput();

return inputList .stream()

.map(this::processInput)

.collect(toList()); }

Implementing processStream() as a Sequential Stream

(16)

16

processStream

() sequentially searches for phrases in lists of input “strings”

protected List<List<SearchResults>> processStream() { List<CharSequence> inputList = getInput();

return inputList .stream()

.map(this::processInput)

.collect(toList());

}

Implementing processStream() as a Sequential Stream

(17)

17

processStream

() sequentially searches for phrases in lists of input “strings”

protected List<List<SearchResults>> processStream() { List<CharSequence> inputList = getInput();

return inputList .stream()

.map(this::processInput)

.collect(toList());

}

Implementing processStream() as a Sequential Stream

(18)

18

processStream

() sequentially searches for phrases in lists of input “strings”

protected List<List<SearchResults>> processStream() { List<CharSequence> inputList = getInput();

return inputList .stream()

.map(this::processInput)

.collect(toList());

}

Implementing processStream() as a Sequential Stream

toList() allocate memory for results, which is less error-prone than the OO version!

(19)

19

processStream

() sequentially searches for phrases in lists of input “strings”

protected List<List<SearchResults>> processStream() { List<CharSequence> inputList = getInput();

return inputList

.stream()

.map(this::processInput) .collect(toList());

}

Implementing processStream() as a Sequential Stream

Return a list of lists of search results denoting how many times a search phrase appeared in each input string

(20)

20

Implementing

processInput() as a

Sequential Stream

(21)

21

processInput() searches an input string for all occurrences of phrases to find

Implementing processInput() as a Sequential Stream

… Stream <SearchResults> Stream <String> List <SearchResults> … List <String> … map(phrase -> searchForPhrase(…)) filter(not(SearchResults::isEmpty)) collect(toList()) 45,000+ phrases Search Phrases stream() Stream <SearchResults>

(22)

22

processInput() searches an input string for all occurrences of phrases to find

List<SearchResults> processInput(CharSequence inputSeq) {

String title = getTitle(inputSeq);

CharSequence input = inputSeq.subSequence(...);

List<SearchResults> results = mPhrasesToFind .stream()

.map(phrase

-> searchForPhrase(phrase, input, title, false)) .filter(not(SearchResults::isEmpty))

.collect(toList()); return results;

}

(23)

23

processInput() searches an input string for all occurrences of phrases to find

List<SearchResults> processInput(CharSequence inputSeq) {

String title = getTitle(inputSeq);

CharSequence input = inputSeq.subSequence(...);

List<SearchResults> results = mPhrasesToFind .stream()

.map(phrase

-> searchForPhrase(phrase, input, title, false)) .filter(not(SearchResults::isEmpty))

.collect(toList()); return results;

}

Implementing processInput() as a Sequential Stream

The inputSeq is a section of a text file managed by the test driver program

(24)

24

processInput() searches an input string for all occurrences of phrases to find

List<SearchResults> processInput(CharSequence inputSeq) {

String title = getTitle(inputSeq);

CharSequence input = inputSeq.subSequence(...);

List<SearchResults> results = mPhrasesToFind .stream()

.map(phrase

-> searchForPhrase(phrase, input, title, false)) .filter(not(SearchResults::isEmpty))

.collect(toList()); return results;

}

Implementing processInput() as a Sequential Stream

(25)

25

processInput() searches an input string for all occurrences of phrases to find

List<SearchResults> processInput(CharSequence inputSeq) { String title = getTitle(inputSeq);

CharSequence input = inputSeq.subSequence(...);

List<SearchResults> results = mPhrasesToFind .stream()

.map(phrase

-> searchForPhrase(phrase, input, title, false)) .filter(not(SearchResults::isEmpty))

.collect(toList()); return results;

}

Implementing processInput() as a Sequential Stream

subSequence() is used to avoid memory copying overhead for substrings

(26)

26

processInput() searches an input string for all occurrences of phrases to find

List<SearchResults> processInput(CharSequence inputSeq) { String title = getTitle(inputSeq);

CharSequence input = inputSeq.subSequence(...);

List<SearchResults> results = mPhrasesToFind

.stream()

.map(phrase

-> searchForPhrase(phrase, input, title, false)) .filter(not(SearchResults::isEmpty))

.collect(toList()); return results;

}

Convert a list of phrases into a stream

(27)

27

processInput() searches an input string for all occurrences of phrases to find

List<SearchResults> processInput(CharSequence inputSeq) { String title = getTitle(inputSeq);

CharSequence input = inputSeq.subSequence(...);

List<SearchResults> results = mPhrasesToFind .stream()

.map(phrase

-> searchForPhrase(phrase, input, title, false))

.filter(not(SearchResults::isEmpty)) .collect(toList());

return results; }

Implementing processInput() as a Sequential Stream

Apply this function lambda to all phrases in input stream & return an output stream of SearchResults

(28)

28

processInput() searches an input string for all occurrences of phrases to find

List<SearchResults> processInput(CharSequence inputSeq) { String title = getTitle(inputSeq);

CharSequence input = inputSeq.subSequence(...);

List<SearchResults> results = mPhrasesToFind .stream()

.map(phrase

-> searchForPhrase(phrase, input, title, false))

.filter(not(SearchResults::isEmpty))

.collect(toList()); return results;

}

Implementing processInput() as a Sequential Stream

Returns output stream containing non-empty SearchResults from input stream

(29)

29

processInput() searches an input string for all occurrences of phrases to find

List<SearchResults> processInput(CharSequence inputSeq) { String title = getTitle(inputSeq);

CharSequence input = inputSeq.subSequence(...);

List<SearchResults> results = mPhrasesToFind .stream()

.map(phrase

-> searchForPhrase(phrase, input, title, false))

.filter(not(SearchResults::isEmpty))

.collect(toList()); return results;

}

Implementing processInput() as a Sequential Stream

This approach uses a method reference along with a negator predicate lambda

(30)

30

processInput() searches an input string for all occurrences of phrases to find

List<SearchResults> processInput(CharSequence inputSeq) { String title = getTitle(inputSeq);

CharSequence input = inputSeq.subSequence(...);

List<SearchResults> results = mPhrasesToFind .stream()

.map(phrase

-> searchForPhrase(phrase, input, title, false)) .filter(((Predicate<String>) SearchResults::isEmpty))

.negate())

.collect(toList()); return results;

}

Implementing processInput() as a Sequential Stream

See docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html#negate

Another approach uses a composed predicate

(31)

31

Implementing processInput() as a Sequential Stream

processInput() searches an input string for all occurrences of phrases to find

List<SearchResults> processInput(CharSequence inputSeq) { String title = getTitle(inputSeq);

CharSequence input = inputSeq.subSequence(...);

List<SearchResults> results = mPhrasesToFind .stream()

.map(phrase

-> searchForPhrase(phrase, input, title, false))

.filter(result -> result.size() > 0)

.collect(toList()); return results;

}

Yet another approach uses a lambda expression

(32)

32

processInput() searches an input string for all occurrences of phrases to find

List<SearchResults> processInput(CharSequence inputSeq) { String title = getTitle(inputSeq);

CharSequence input = inputSeq.subSequence(...);

List<SearchResults> results = mPhrasesToFind .stream()

.map(phrase

-> searchForPhrase(phrase, input, title, false))

.filter(not(SearchResults::isEmpty))

.collect(toList()); return results;

}

These are both intermediate operations

Implementing processInput() as a Sequential Stream

(33)

33

Implementing processInput() as a Sequential Stream

processInput() searches an input string for all occurrences of phrases to find

List<SearchResults> processInput(CharSequence inputSeq) { String title = getTitle(inputSeq);

CharSequence input = inputSeq.subSequence(...);

List<SearchResults> results = mPhrasesToFind .stream()

.map(phrase

-> searchForPhrase(phrase, input, title, false)) .filter(not(SearchResults::isEmpty))

.collect(toList());

return results; }

This terminal operation triggers intermediate operation processing & yields a list result

(34)

34

Implementing processInput() as a Sequential Stream

processInput() searches an input string for all occurrences of phrases to find

List<SearchResults> processInput(CharSequence inputSeq) { String title = getTitle(inputSeq);

CharSequence input = inputSeq.subSequence(...);

List<SearchResults> results = mPhrasesToFind

.stream() .map(phrase

-> searchForPhrase(phrase, input, title, false)) .filter(not(SearchResults::isEmpty))

.collect(toList()); return results;

}

This terminal operation triggers intermediate operation processing & yields a list result

(35)

35

processInput() searches an input string for all occurrences of phrases to find

List<SearchResults> processInput(CharSequence inputSeq) { String title = getTitle(inputSeq);

CharSequence input = inputSeq.subSequence(...);

List<SearchResults> results = mPhrasesToFind .stream()

.map(phrase

-> searchForPhrase(phrase, input, title, false)) .filter(not(SearchResults::isEmpty))

.collect(toList());

return results;

}

The list result is returned back to the map() operation in processStream()

(36)

36

End of Learn How to

Implement Java Sequential

SearchStreamGang Hook

See www.javaspecialists.eu/archive/Issue230.html See livelessons/utils/SearchResults.java SearchStreamGang/src/main/java/livelessons/utils/SharedString.java ee SearchStreamGang/src/main/java/livelessons/utils/StreamsUtils.java ee docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html#negate

References

Related documents

In memory of Harold Taub, beloved husband of Paula Taub by: Karen &amp; Charles Rosen.. Honouring Maria Belenkova-Buford on her marriage by: Karen &amp;

In this study, the monthly Currency sale rates (DS) and Export (X) series are considered to investigate whether the X and DS series were affected by each other in the turning

To address these questions, the following goals were set: (a) to reproduce field explosions pertaining to primary blast injury as accurate as possible in a controlled

 Note that if we declared the parameter c to be of type List&lt;Comparable&gt; then we could not sort an object of type List&lt;String&gt; (even though String is a subtype

“ the seven words of our LORD on

One school of thought argues that training in competencies like Communication skills and Customer relationship management leads to an increase in turnover, while the other

SEQUENTIAL_LOOPS executed in 1638 msecs SEQUENTIAL_STREAM executed in 1958 msecs Ending SearchStreamGangTest map(phrase -&gt; searchForPhrase(…))

 Note that if we declared the parameter c to be of type List&lt;Comparable&gt; then we could not sort an object of type List&lt;String&gt; (even though String is a subtype