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.
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
Spliterator to the rescue
In order to implement your own Stream on an arbitrary input is writing a
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
This only leaves the actual processing of the
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
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
hasNext functionality required to implement a
Proof on the pudding
Below is a test case that shows how you can use this
Iterable to parse a line of key values.
The complete implementation can be found at [GitHub]