如何使用字符串生成器

How to use stringBuilder

我有一个功能和技术负责人审查代码并说: 为什么这个if语句?这基本上是相同的消息。如果要自定义,请使用带有该类型的字符串生成器。 怎么改啊,谁能帮帮我?

private Optional<String> validatePrimaryPath(SalesChannelType salesChannelCode, List<String> primaryPathList) {

  if (CollectionUtils.isEmpty(primaryPathList)) {
    if (salesChannelCode.equals(SalesChannelType.HEB_TO_YOU)) {
      return Optional.of("Customer Hierarchy is mandatory field for HebToYou.");
    } else {
      return Optional.of("Customer Hierarchy is mandatory field.");
    }
  }

  return Optional.empty();
}

为防止多次写入相同的(部分)字符串文字,您可以:

  • 公共部分使用常量:

    if (CollectionUtils.isEmpty(primaryPathList)) {
        final String COMMON = "Customer Hierarchy is mandatory field";
        if (salesChannelCode.equals(SalesChannelType.HEB_TO_YOU)) {
            return Optional.of(COMMON + " for HebToYou.");
        } else {
            return Optional.of(COMMON + ".");
        }
    }
    
  • 使用 StringBuilder:

    构建字符串
    if (CollectionUtils.isEmpty(primaryPathList)) {
        StringBuilder buf = new StringBuilder("Customer Hierarchy is mandatory field");
        if (salesChannelCode.equals(SalesChannelType.HEB_TO_YOU)) {
            buf.append(" for HebToYou");
        }
        return Optional.of(buf.append('.').toString());
    }
    

就我个人而言,我会保留问题中的代码,特别是如果您可能需要支持文本的非英语版本,因为在其他语言中,额外的文本可能不会存在。

首先,不要使用原始类型。其次,我不同意使用 StringBuilder 构建消息是一种改进;但是,由于这就是您想要的,我将向您展示可能的意图。像,

private Optional<String> validatePrimaryPath(SalesChannelType salesChannelCode, 
                List<String> primaryPathList) {
    if (CollectionUtils.isEmpty(primaryPathList)) {
        StringBuilder sb = new StringBuilder(
                    "Customer Hierarchy is mandatory field");
        if (salesChannelCode.equals(SalesChannelType.HEB_TO_YOU)) {
            sb.append(" for HebToYou");
        }
        sb.append(".");
        return Optional.of(sb.toString());
    }

    return Optional.empty();
}

请注意,我已将方法 returns 指定为 Optional<String> 并在您编写 OptionalList 时采用 List<String> 而未指定类型您正在使用原始类型。

就我个人而言,我认为您的代码还可以,但如果您仍想使用 StringBuilder

,我对此有一个建议
private Optional validatePrimaryPath(SalesChannelType salesChannelCode, List primaryPathList) {
    if (CollectionUtils.isEmpty(primaryPathList)) {
        StringBuilder sb = new StringBuilder("Customer Hierarchy is mandatory field.");
        if (salesChannelCode.equals(SalesChannelType.HEB_TO_YOU)) {
            sb.insert(sb.length()-1, " for HebToYou");
        }
        return Optional.of(sb.toString());
    }
    return Optional.empty();
}

指定两个字符串文字意味着没有运行时开销。当所有参数都是编译时常量时,您可以使用字符串连接实现相同的效果。相反,使用 StringBuilder 总是意味着运行时操作。您可以在 .

中阅读更多关于“StringBuilder+ 神话”的信息

您通常可以降低代码的句法复杂性:

private Optional<String> validatePrimaryPath(
    SalesChannelType salesChannelCode, List<String> primaryPathList) {

    final String prefix = "Customer Hierarchy is mandatory field";
    final String general = prefix + ".", forHebToYou = prefix + " for HebToYou.";

    return Optional.of(
            salesChannelCode.equals(SalesChannelType.HEB_TO_YOU)? forHebToYou: general)
        .filter(s -> CollectionUtils.isEmpty(primaryPathList));
}

这强调您正在做同样的事情,只是数据略有不同,并使用 Optional 的语义而不是 if 语句。如果您决定外部化实际的字符串,则实际代码不需要更改。

请注意,如果SalesChannelTypeenum,则不需要equals,您可以直接使用salesChannelCode == SalesChannelType.HEB_TO_YOU