Java8: finding the best way to parse key-value string text

I have a string of text strings.
Some lines are in key: value format. Others should be ignored.
I have a fixed (predefined) list of keys that I need to retrieve values ​​and put them in a HashMap.
So, I am 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 to implement parsing in Java 8?

+4
source share
3 answers

According to your current problem operator. You can try under the code that ..

  • Reads a file and creates a stream from it
  • Compiles each line with regex
  • ,
  • Map

:

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)));
}

, ,

+3
// 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);
      }))

, . java.lang.IllegalStateException: Duplicate key

+2

split , , . , , BufferedReader.

Java 8:

static String memoText = "foo: fooValue\r\n" +
                         "otherKey: otherValue\r\n" +
                         "# something else like a comment line\r\n" +
                         "bar: barValue\r\n";

static Map<String, String> parseKeysValues(String memoText) {
    Pattern pattern = Pattern.compile("([a-zA-Z]+)\\s*:\\s*(.*)");
    Set<String> allowedKeys = new HashSet<>(Arrays.asList("foo", "bar"));
    return new BufferedReader(new StringReader(memoText)).lines()
        .map(pattern::matcher)
        .filter(Matcher::matches)
        .filter(m -> allowedKeys.contains(m.group(1)))
        .collect(Collectors.toMap(m -> m.group(1), m -> m.group(2)));
}

, , , , . , , , .. filter(Matcher::matches) . 1 , 2 - , , .

, . , toMap, . , (a, b) -> b " ".

Java 9 :

static Map<String, String> parseKeysValues9(String memoText) {
    Set<String> allowedKeys = Set.of("foo", "bar");
    return new Scanner(memoText).findAll("(?m)^([a-zA-Z]+)\\s*:\\s*(.*)$")
        .filter(mr -> allowedKeys.contains(mr.group(1)))
        .collect(Collectors.toMap(mr -> mr.group(1), mr -> mr.group(2), (a, b) -> b));
}

Set.of static factory. Scanner BufferedReader. findAll MatchResult, . , , , . ^ $ . (?m), MULTILINE, ^ $ , . , , , . toMap.

+2
source

Source: https://habr.com/ru/post/1677951/


All Articles