如何在String对象上使用Java 8 forEach来编码值?

时间:2017-08-23 01:53:10

标签: java java-8

我正在尝试使用Java 8 ForEach编写以下等效内容来编码字符串数组。

public static void encode(String... stringsToEncode) {
  for (int i = 0; i < stringsToEncode.length; i++) {
     stringsToEncode[i] = URLEncoder.encode(stringsToEncode[i], "UTF-8");
  }
}
// stringsToEncode = 10+111569+++8 as expected.

我已实施以下内容:

public static void encodeUsingForEach(String... stringsToEncode)
  List<String> listOfStrings = Arrays.asList(stringsToEncode);
  listOfStrings.forEach(s -> {
    try {
      s = URLEncoder.encode(s, "UTF-8");
  } catch (UnsupportedEncodingException e) {
      throw new AssertionError("UTF-8 is unknown");
    }
 });
}
// listOfStrings = [10 11, 156, 9   8]

我缺少什么,以便encodeUsingForEach()的输出等同于encode()方法的输出?

2 个答案:

答案 0 :(得分:3)

您无法使用forEach()替换值,因为只有消耗对象而不会返回它们。 lambda中的重新分配实际上没有做任何事情,因为arguments are passed by value in Java。相反,请尝试使用流来映射值并生成新列表:

List<String> listOfStrings = Arrays.stream(stringsToEncode)
        .map(s -> {
            try {
                return URLEncoder.encode(s, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new AssertionError("UTF-8 is unknown");
            }
        })
        .collect(Collectors.toList());

答案 1 :(得分:1)

在lambda表达式中,s是列表的成员之一,列表指向内存中的该位置。因此,如果s是一个对象并且您更改了某些字段,那么每个事情都会正确但现在您正在替换存储在s中的对象的地址而不在列表中进行更新。因此,通过这种替换,你只会失去参考。