This post describes a implementation for streaming a String
of space separated Key Values with Java 8. In order to implement a streaming keyvalue reader two simple classes are implemented. One to handle navigation in the string and one to make a Iterable
from the String.
The implementation I provide is basic but has enough extension points to meet more extensive requirements.
The problem.
We all have faced the same problem when dealing with data from other sources. Question is always do I take a existing library of a DIY version. All implementations I know of are based on the pre Java 8 era. For the purpose of my current project (Java 8) I wanted to stream a String of Key Values so I could easily perform Streaming operations on it.
A naive approach
A quick start for implementing the required functionality is doing a multiple split on the input string i.e. split on the entry separator and next on the value separator. This might work but you always run into issues with escaped characters and such. So this would not work :-(
The Streaming approach
Functional programming is sort of available in Java 8. We can do streams and lambda’s. Processing a stream of KeyValue in a more functional manner has advantages.
Below are the steps I performed to make a String
of keyvalues available asa a Stream
Spliterator
to the rescue
In order to implement your own Stream on an arbitrary input is writing a Spliterator
. Spliterators
are not that easy to implement, all kinds of concurrency issues come up with that one. It is much simpler to implement an Iterable<Map.Entry<String, String>>
. In that case you only need to implement @Override
a single method to start working with the data as a Stream
.
This only leaves the actual processing of the String
data.
Parsing the String
data.
When parsing the data you need to keep track of the previous characters and mark the start of either a Key or Value. For this purpose I created a KeyValueReader
. This reader reads the string in a forward motion. For example to read a single KeyValue you skipUntil
you find the =
sign. When this is found you have the key. Next you skip until the "
character. This is the start of your value. skip again until the "
and you have the value.
Making the KeyValueReaderIterable
The KeyValueIterable
is an implementation of the Iterable<T>
interface. The only method that you need to provide is the Iterator<T> iterator()
. Which in his turn is the implementation of the Iterator
. Implementing a Iterator
is straight forward. As mentioned The KeyValueReader
can navigate forwards in a String. With that it is easy to achieve the next
and hasNext
functionality required to implement a Iterator
.
Proof on the pudding
Below is a test case that shows how you can use this Iterable
to parse a line of key values.
(https://github.com/elucidator/keyvalue-parser)
The complete implementation can be found at [GitHub]