【问题标题】:Java - check if under_score string is in a list of lowerCamel stringsJava - 检查 under_score 字符串是否在 lowerCamel 字符串列表中
【发布时间】:2021-05-10 08:32:59
【问题描述】:

考虑以下键(under_score)和字段(lowerCamel):

keys   = ["opened_by","ticket_owner","close_reason"]
fields = ["openedBy","ticketOwner","closeReason"]

我正在寻找一种有效的 Java 方法来检查 key 是否在 fields 中,我希望在其中返回 true

fields = ["openedBy","ticketOwner"]

return fields.contains("opened_by"))   //true

我的代码:

Set<String> incidentFields = Arrays
            .stream(TicketIncidentDTO.class.getDeclaredFields())
            .map(Field::getName)
            .collect(Collectors.toSet()
            );


responseJson.keySet().forEach(key ->{
           
            if (incidentFields.contains(key)) 
            {
                //Do something
            }
        });

我可以用下划线替换所有小写,但我正在寻找更有效的方法。

【问题讨论】:

  • 这能解决您的问题吗? stackoverflow.com/questions/10310321/…
  • 谢谢,但不完全是,我可以用下划线替换所有小写,但我正在寻找更有效的方法。也许是一些忽略大小写格式或类似的方法。
  • Sets、Maps,默认调用equals()方法。这里没有“简单”。您要么实现使用不同类型比较的非常特殊的 Set,要么硬着头皮保留多个包含这些“转换”ID 的集合。请注意,忽略大小写并没有真正的帮助,因为它会留下“_”来使比较失败。
  • 你能澄清一下你认为“用下划线替换小写字母”效率低下的地方吗?在我看来,您有两种选择:(1)最初将您的字段转换为下划线而不是 CamelCase 表示法,(2)保持字段不变,而是在每次查找期间将键从下划线转换为 CamelCase。如果您的字段相对较少且查找次数较多,则方法 (1) 是迄今为止更有效的方法。

标签: java collections java-stream camelcasing


【解决方案1】:

尝试使用来自Commons TextCaseUtils

// opened_by -> openedBy
private String toCamel(String str) {
    return CaseUtils.toCamelCase(str, false, new char[] { '_' });
}

List<String> keys = Arrays.asList("opened_by", "ticket_owner", "close_reason", "full_name");

List<String> fields = Arrays.asList("openedBy", "ticketOwner", "closeReason");

keys.forEach(t -> {
    // check
    if (fields.contains(toCamel(t))) {
        System.out.println(t);
    }
});

【讨论】:

    【解决方案2】:

    如果您没有 abcXyz (abc_xyz) 和 abCxyz (ab_cxyz) 之类的字段(拼写相同但单词组合不同的字段),那么一种解决方案是替换 "_" "" 为空,然后使用 equalsIgnoreCase 与 fieldName 进行比较。另一种但类似的解决方案是将每个字段名转换为小写,然后在将“_”替换为“”后将其与驼峰式字符串进行比较。与第一种方法相比,这可能会消除额外循环的使用。

    
    Set<String> fields= Arrays.stream(TicketIncidentDTO.class.getDeclaredFields())
                              .map(Field::getName)
                              .map(String::toLowerCase)
                              .collect(Collectors.toSet());
    
    
    responseJson.keySet()
                .filter(key -> fields.contains(key.replaceAll("_","")))
                .forEach(key -> {
                    // do something..
                });
    

    【讨论】:

      【解决方案3】:

      一个简单的toCamel方法:

      private String toCamel(String str) {
          String[] parts = str.split("_");
          StringBuilder sb = new StringBuilder(parts[0]);
          for (int i=1; i < parts.length ; i++) {
              String part = parts[i];
              if (part.length() > 0) {
                  sb.append(part.substring(0, 1).toUpperCase()).append(part.substring(1));
              }
          }
          return sb.toString();
      }
      

      现在使用完全相同的方法:

      keys.forEach(t -> {
          if (fields.contains(toCamel(t))) {
              System.out.println("Fields contain " + t);
          } else {
              System.out.println("Fields doesn't contain " + t);
          }
      });
      

      我可以用下划线替换所有小写,但我正在寻找更有效的方法。

      使用Set 作为keysfields 的数据结构,在查找中非常有效。此外,它适用于这个用例,因为在 JSON 中有重复的键是没有意义的。

      【讨论】:

        猜你喜欢
        • 2013-01-09
        • 1970-01-01
        • 2013-04-29
        • 2015-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多