-1
static TreeMap<Integer, String> parseElementsBeforeOpenBracket(String inValue) {
    StringTokenizer tokenizer = new StringTokenizer(inValue, "[]", true);
    TreeMap<Integer, String> mapElements = new TreeMap<>();
    int i = 0;
    while (tokenizer.hasMoreElements()) {
        String s = (String) tokenizer.nextElement();
        mapElements.put(i, s);
        i += s.length();
    }
    return mapElements;
}

Expecting: something like TreeMap<Integer, String> mapElements = xxx.stream()...Collectors.toMap()

aozhinsky
  • 1
  • 2
  • 2
    I would advice against using a lambda. The current process has a state (variable `i`). While we can introduce states in lambdas, this is discouraged. – Turing85 Jul 30 '23 at 21:25
  • 1
    I would advise against using `StringTokenizer`: [StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/StringTokenizer.html#nextElement()) So something of that great age is not going to be a natural fit with modern Java features. Please give an example of the text you're processing – g00se Jul 30 '23 at 21:42
  • The example of the text is "ozh2[ 2a]xyz4[ 4b3[ 3c]]abc5[ 5]abcde" The method is part of the solution of the problem where pattern like "2[abcd]" is substituted by "abcdabcd". Patterns like 4[ 4b3[ 3c]] with "child" sub-patterns are allowed. – aozhinsky Jul 31 '23 at 00:38
  • I tried to use String.split, but I failed to find proper argument to include both '[' and ']' – aozhinsky Jul 31 '23 at 00:42

1 Answers1

0

I don't know how to use lambda, but, as the official doc says you can use Mathch and Pattern under java.util.regex package instead of StringTokenizer:

private static final Pattern PATTERN = Pattern.compile("[^\\[\\]]+|\\[|\\]");
    
    public static TreeMap<Integer, String> parseElementsBeforeOpenBracket(String inValue) {
        TreeMap<Integer, String> mapElements = new TreeMap<>();
        Matcher matcher = PATTERN.matcher(inValue);
        int i = 0;
        while (matcher.find()) {
            String s = matcher.group();
            mapElements.put(i, s);
            i += s.length();
        }
        return mapElements;
    }

I tested with ozh22a]xyz4[4b3[3c]]abc5[5]abcde and got the same result as your code {0=ozh22a, 6=], 7=xyz4, 11=[, 12=4b3 , 15=[, 16=3c, 18=], 19=], 20=abc5, 24=[, 25=5, 26=], 27=abcde}

Maybe you can't think of [^\\[\\]]+|\\[|\\] very quickly, but observing your code results can be divided into three parts:

  1. Consecutive characters that are not [ or ] -> [^\\[\\]]+
  2. [ -> \\[
  3. ] -> \\]

\\ is an escape

If you are not familiar with the methods of the Matcher class, please see Module java.base Package java.util.regex Class Matcher.

If you use jdk9 and above, you can use the Matcher.result() method, such as matcher.results().collect(TreeMap::new, (map, matchResult) -> map.put(matchResult.start(), matchResult.group()), TreeMap::putAll);

This can directly get a TreeMap result.

Please see Matcher.results().I didn't test it because I'm using JDK8.

I am not very good at English, I use Google Translate, which may affect reading, please forgive me. Hope to help you.

HuaJFrame
  • 72
  • 7