Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java8: Looking for a better way of parsing a text of "key: value" lines

Tags:

java

java-8

I have a String of text lines.
Some of the lines have a format of "key: value". Others should be ignored.
I have a fixed (pre-defined) list of keys that I needs to extract values for and put into a HashMap.
So, I'm doing something like this:

BufferedReader reader = new BufferedReader(new StringReader(memoText));

reader.lines().forEach(line->{
    if(line.startsWith("prefix1")){
        // Some code is required here to get the value1
    }  
    else if(line.startsWith("prefix2")){
        // Some code is required here to get the value2
    }  
    ...
}

Is there a better way of implementing the parsing in Java 8?

like image 738
spoonboy Avatar asked Mar 09 '23 00:03

spoonboy


2 Answers

As per you current problem statement. You can try below code which..

  • Reads a file and creates a stream out of it
  • Compiles each string using regex
  • Filter out all the strings which do not match with pattern
  • Read the matching groups to Map

You may want to change it as per your needs:

import static java.util.stream.Collectors.toMap;
//skipped
Pattern pattern = Pattern.compile("([a-zA-Z]+)\\s*:\\s*(.*)");
try (Stream<String> stream = Files.lines(Paths.get("<PATH_TO_FILE>"))) {
    Map<String, String> results =
            stream.map(pattern::matcher)
                    .filter(Matcher::find)
                    .collect(toMap(a -> a.group(1), a -> a.group(2)));
}

Let me know, if this is not what you are looking for

like image 116
Amit Phaltankar Avatar answered Apr 26 '23 14:04

Amit Phaltankar


// define your fixed keys in a list
List<String> keys = Arrays.asList("key1", "key2");
reader.lines()
      // use filter instead of if-else
      .filter(line -> line.indexOf(":")>-1 && keys.contains(line.substring(0, line.indexOf(":"))))
      // collect in to a map
      .collect(Collectos.toMap(line -> {
          return line.substring(0, line.indexOf(":"));
      }, line -> {
          return line.substring(line.indexOf(":") + 1);
      }))

But you must make sure every line has the different key. Or it will throw java.lang.IllegalStateException: Duplicate key

like image 31
John Avatar answered Apr 26 '23 13:04

John