【问题标题】:Java 8 convert integers to String with LambdaJava 8 使用 Lambda 将整数转换为字符串
【发布时间】:2017-08-30 01:45:27
【问题描述】:

我正在尝试创建一个返回随机字母字符字符串的函数,但我正在尝试使用 lambdas 来实现,我的函数如下所示:

public static String nextString() {
  return IntStream.range(0, 10).map(i -> getRandomChar()).XXX
}

private static Character getRandomChar() {
  //returns a random Character object
}

我不知道在 XXX 上设置什么。

我以类似的方式修复了它:

public static String nextString() {
    StringBuilder randomString = new StringBuilder();
    IntStream.range(0, stringLenght).forEach(i -> randomString.append(getRandomChar()));
    return randomString.toString();
}

但我不希望每次使用该方法时都创建一个新的 StringBuilder 并为一个简单的方法保留状态和变量。

【问题讨论】:

  • 如果我尝试return IntStream.range(0, strLenght).map(i -> getRandomChar()).collect(Collectors.joining(""));got 编译问题,我之前尝试过,因为这个错误我发布了我的问题

标签: java lambda


【解决方案1】:

类似这样的:

public static String nextString() {
    return IntStream.range(0, 10).boxed().map(i -> getRandomChar(i)).collect(Collectors.joining());
}

private static String getRandomChar(int i) {
    return String.valueOf((char)i);
}

【讨论】:

  • 我不明白为什么此代码仅在 getRandomChar 返回字符串时有效,但在返回字符时无效
  • 因为 Collectors.joining() 需要 Stream。您可以像这样创建自己的收集器: Collector collector = Collector.of(StringBuilder::new, StringBuilder::append, (r1, r2) -> { r1.append(r2); return r1; }, StringBuilder::toString);
【解决方案2】:

不清楚getRandomChar() 做了什么,是否值得围绕它构建另一个 Stream 操作。首先,流式传输随机值要简单得多。

例如,以下代码生成由A-Z 范围内的大写字母组成的随机字符串:

public static String nextString() {
    return ThreadLocalRandom.current().ints(stringLength, 'A', 'Z'+1)
        .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
        .toString();
}

如果预期字符不形成连续范围,您可以使用字符串常量命名允许的字符,例如

public static String nextString() {
    String allowed = "XO+";
    return ThreadLocalRandom.current().ints(stringLength, 0, allowed.length())
        .map(allowed::charAt)
        .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
        .toString();
}

当然,这个收集器不会像Collectors.joining() 那样隐藏StringBuilder,但另一方面,这个操作没有装箱开销,也不会创建临时字符串。

你可以使用类似的操作来构建字符池String

static final String ASCII_LETTERS_AND_NUMBERS =
        IntStream.concat(IntStream.concat(
            IntStream.rangeClosed('A', 'Z'), IntStream.rangeClosed('a', 'z')),
            IntStream.rangeClosed('0', '9'))
        .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
        .toString();
public static String nextString() {
    return ThreadLocalRandom.current()
        .ints(stringLength, 0, ASCII_LETTERS_AND_NUMBERS.length())
        .map(ASCII_LETTERS_AND_NUMBERS::charAt)
        .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
        .toString();
}

或者,挑战随机字符串的读者:

static final String ALL_LETTERS_AND_NUMBERS =
    IntStream.rangeClosed(32, Character.MAX_VALUE)
        .filter(Character::isLetterOrDigit)
        .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
        .toString();
public static String nextString() {
    return ThreadLocalRandom.current()
        .ints(stringLength, 0, ALL_LETTERS_AND_NUMBERS.length())
        .map(ALL_LETTERS_AND_NUMBERS::charAt)
        .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
        .toString();
}

【讨论】:

  • 我非常喜欢你的回答方式。而这个ThreadLocalRandom.current().ints(stringLength, 'A', 'Z'+1) 直到现在你都不知道我需要多少次。非常感谢
  • 嗯,我知道,它可以很容易地适应从 List 或数组中进行选择。
猜你喜欢
  • 2017-04-13
  • 1970-01-01
  • 2015-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-01
相关资源
最近更新 更多