【问题标题】:How to find a String that startsWith other String in Map<String, String>, by the most efficient way如何以最有效的方式在 Map<String, String> 中找到以其他字符串开头的字符串
【发布时间】:2021-05-25 07:03:27
【问题描述】:

我收集了很多String就是包名,把这些字符串作为key放到map中,value就是key的别名。 (我选择了 TreeMap

喜欢:

Map<String, String> packages = new TreeMap<>();
packages.put("org.springframework.boot.actuate", "SpringBoot@Actuate");
packages.put("org.springframework.boot.aop", "SpringBoot@AOP");
packages.put("org.apache.ibatis", "Mybatis@Core");
packages.put("org.mybatis.spring", "Mybatis@Spring");
packages.put("org.slf4j", "SLF4j@Core");
packages.put("ch.qos.logback.core", "Logback@Core");

那么,方法参数为全限定类名的指定值,我需要返回alias(value)对应包(key)的值

喜欢:

// className: ch.qos.logback.core.layout.EchoLayout
@Nullable
String find(String className) {
  // method implementation
  return ""; // return Logback@Core
}

我想使用 TreeMap.subMap() 从第一级包名逐步查找,并递归进行

喜欢:

// !!! pseudocode !!!
@Nullable
String find(String className, int position) {
  int idx = className.indexOf(".", position);
  String pkg = className.substring(0, idx);
  
  Map<String, String> sub = packages.subMap(pkg, pkg + " ");
  if (sub.size() == 1) {
    return ""; // found it
  } else {
    return ""; // other situations
  }

  return ""; // not found any alias
}

我不确定这是最有效的方法,这个方法会被频繁调用。谁能提供更好的解决方案?

【问题讨论】:

    标签: java string performance dictionary


    【解决方案1】:

    我认为从参数中的 FQCN 开始并从末尾删除一个级别并检查地图中每个级别的存在会更简单。 FQCN 可能会变得很长,但实际上,在最坏的情况下,您可能会看到 10-20 次存在检查。另外,如果你选择这种方法,我会使用 HashMap 而不是 TreeMap,所以查找是 O(1)。

    示例代码:

    import java.util.Collection;
    import java.util.Map;
    import java.util.stream.Collectors;
    
    import java.util.HashMap;
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;
    class Main {
    
      static Map<String, String> packages = new HashMap<>();
    
      public static void main(String[] args) {
        
        packages.put("org.springframework.boot.actuate", "SpringBoot@Actuate");
        packages.put("org.springframework.boot.aop", "SpringBoot@AOP");
        packages.put("org.apache.ibatis", "Mybatis@Core");
        packages.put("org.mybatis.spring", "Mybatis@Spring");
        packages.put("org.slf4j", "SLF4j@Core");
        packages.put("ch.qos.logback.core", "Logback@Core");
        
    
        System.out.println(find("ch.qos.logback.core.layout.EchoLayout"));
    
      }
    
      // className: ch.qos.logback.core.layout.EchoLayout
      static String find(String className) {
      // method implementation
    
      List<String> classNameParts = Arrays.asList(className.split("\\."));
    
      // Checks for entries in the map in the following order
      // ch.qos.logback.core.layout.EchoLayout
      // ch.qos.logback.core.layout
      // ch.qos.logback.core
      // ch.qos.logback
      // ch.qos
      // ch
      for(int i = classNameParts.size(); i >= 0; i--){
          String packagePart = classNameParts.stream().limit(i).collect(Collectors.joining("."));
          if(packages.containsKey(packagePart)){
            return packages.get(packagePart);
          }
      }
    
      // No entry found
      return null;
    }
    }
    

    试试Repl.it

    【讨论】:

    • 其实比我想象的要好。功能很好,然后我需要关心性能
    • 其实这是最好的办法。
    猜你喜欢
    • 1970-01-01
    • 2011-11-02
    • 1970-01-01
    • 1970-01-01
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多