使用Lambda表达式使用HashMap替换字符串中的字符

时间:2016-07-07 13:21:27

标签: java lambda

所以我正在开展一个项目,我必须将包含希腊字母的字符串转换为包含此字母的英文表示的字符串。希望α成为alphaΑ成为Alpha

我创建了一个HashMap,它具有从Unicode Character到普通String的适当转换。

我使用了一个简单的For循环来检查输入Char中的StringKey中的HashMap,如果是{我将使用StringBuilder附加替代品。这是我用来执行此操作的代码:

char[] ca = snippet.toCharArray();
        StringBuilder out = new StringBuilder();
        for (char c : ca) {
            if (GREEK_LETTER_DICT.containsKey(Character.toString(c))) {
                out.append( GREEK_LETTER_DICT.get(Character.toString(c)));
            } else {
                out.append(c);
            }
        }
    return out.toString();

这是一个以String为输入的公共静态方法。 我想知道的是,是否可以使用lambda表达式执行相同的操作?我已经找到了一些替代Character String的解决方案,但他们没有使用HashMap / Dictionary

我理解为了使用lambda表达式将它转换为lambda表达式是完全没用的,但是因为我有另外7个函数将我的代码缩短了近60%我想看看它是否完全可以在"一行"代码这样我就可以减少我使用的单独方法的数量并获得更清晰的代码。

到目前为止,我找到了一种方法,可以使用以下内容将String转换为Stream

String.chars()

然后使用

将此IntStream转换为Stream<Character>
.mapToObj(ch -> (char) ch)

并过滤以查看Character是否在HashMap

.filter(ch -> (GREEK_LETTER_DICT.containsKey(ch)))

问题在于我无法

  1. 将原始Character附加到输出String,如果它不在HashMap
  2. Character替换为HashMap
  3. 中的字符串

    所以对这两点的任何帮助都表示赞赏。我发现有时候我认为错误的方法是因为我没有看到Character中的String是否等于选项列表中的Character,我应该检查一下选项列表返回正index。所以这个(PseudeoCode):

    "StringWithOptions".indexOf('characterLiteral')

    而不是:

    Character.equals("One|of|these")

4 个答案:

答案 0 :(得分:4)

怎么样:

public static String replaceGreekLetters(String snippet) {
    return snippet
            .chars()
            .mapToObj(c -> (char) c)
            .map(c -> GREEK_LETTER_DICT.getOrDefault(c, c.toString()))
            .collect(Collectors.joining());
}

答案 1 :(得分:2)

我会做这样的事情:

str
    .chars()
    .forEach(
        character -> out.append(
            GREEK_LETTER_DICT.getOrDefault(Character.toString(c), c)
        )
    );

答案 2 :(得分:2)

使用Steams有几个很好的解决方案。我更喜欢更简单的那些:

  • 避免从char转换为String
  • 避免在Stream pipline之外使用StringBuffer
  • 使用预定义的收集器
public class ReplaceGreek {

    private Map<String, String> DICT = new HashMap<>();
    {
        DICT.put("α", "alpha");
    }

    public String replace(final String original) {
        return Arrays.stream(original.split(""))
                .map(c -> DICT.getOrDefault(c, c))
                .collect(Collectors.joining());
    }
}

它甚至有效!

public class ReplaceGreekTest {

    @Test
    public void test() {
        ReplaceGreek rg = new ReplaceGreek();
        String greek = "This is greek: α";

        String nogreek = rg.replace(greek);

        assertEquals("This is greek: alpha", nogreek);
    }

}

答案 3 :(得分:1)

因此,使用SMAMartin Seeler中的代码,我能够让它发挥作用。生成的代码现在返回一个String,其结果正确,并通过了我的所有单元测试。

这是结果代码:

    return snippet.chars()
            .mapToObj(c -> (char) c)
            .collect(Collector.of(StringBuilder::new,
                    (stringBuilder, c) -> stringBuilder.append(GREEK_LETTER_DICT.getOrDefault(c,c.toString())),
                    StringBuilder::append,
                    StringBuilder::toString));

来自SMA的代码存在一个问题:HashMap使用<Character, String>而非<String, String>。所以我不得不改变#getOrDefault的参数。将此与.mapToObj(c -> (char) c)相结合就可以了。

现在让我们看看我是否可以改变这个:

(stringBuilder, c) -> stringBuilder.append(GREEK_LETTER_DICT.getOrDefault(c,c.toString())),
                        StringBuilder::append

类似于StringBuilder::append(GREEK_LETTER_DICT.getOrDefault(c,Character.toString(c))