Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 字符串。包含VS集合<;字符串>。包含VS Regex String.matches()_Java_String_Set - Fatal编程技术网

Java 字符串。包含VS集合<;字符串>。包含VS Regex String.matches()

Java 字符串。包含VS集合<;字符串>。包含VS Regex String.matches(),java,string,set,Java,String,Set,我在两个文件中有两组不太长的字符串(200~500个单词),如下所示: File1 File2 this window that good word work java fine book home 所有独特的词语 现在,首先从文件中读取字符串(逐行),并将其存储在: Set-set1 Set-set2:看起来可能是这样的:[这个,那个,单词,java,书]和[窗口,好,工作

我在两个文件中有两组不太长的字符串(200~500个单词),如下所示:

File1          File2

this           window
that           good
word           work
java           fine
book           home
所有独特的词语

现在,首先从文件中读取字符串(逐行),并将其存储在:

  • Set-set1 Set-set2
    :看起来可能是这样的:
    [这个,那个,单词,java,书]
    [窗口,好,工作,好,家]
  • String-str1-String-str2
    :可能是这样的:
    str1:thisthatwordjava
    str2:windowgoodworkfinehome
    可以是
    str1:this,That,word,java
    (用逗号分隔)
  • 现在有三种方法可以检查单词
    home
    ,其中
    Set
    String
    将出现:

  • 使用
    set1/2.contains(“主页”)
  • 使用str1/2.contains(“主目录”)
  • 使用str1/2。匹配(“主”)
  • 以上所有方法都可以,但哪一个最好

    注意:这个问题的目的是因为检查字符串的频率非常高

    不要做性能假设 是什么让您认为String.contains具有“更好的性能”

    除非是非常简单的情况,否则不会发生以下情况:

    • 你的字符串列表很短
    • 要比较的字符串很短
    • 您希望执行一次性查找
    对于所有其他情况,
    Set
    方法将更好地扩展和工作。当然,与单个字符串相比,集合会有内存开销,但即使要存储数百万个字符串并比较长字符串,O(1)查找也会保持不变

    为正确的作业提供正确的数据结构和算法 使用更安全和更稳健的设计,尤其是在这里,它不是一个难以实现的解决方案。正如你提到的,你会经常检查,那么一套方法对你来说肯定更好

    此外,String.contain将是不安全的,因为如果两者都有匹配的字符串和子字符串,则查找将失败。正如kennytm在评论中所说,如果我们使用您的示例,并且您的列表中有“java”字符串,那么查找“ava”将匹配它,这显然是您不想要的

    选择正确的一组 不过,您可能不想使用简单哈希集或调整其设置。例如,如果您的集合只创建一次,但经常检查,则可以考虑一个番石榴iMunababele.

    例子 假设您想要一个不可变的集合(正如您所说的从文件中读取字符串列表),我会这样做。这是即时的,没有验证,所以请原谅缺乏仪式

    使用Java8+Guava
    import com.google.common.collect.ImmutableSet;
    导入com.google.common.io.Files;
    导入com.google.common.base.Splitter;
    最终设置lookupTable=ImmutableSet.copyOf(
    Splitter.on(',')
    .trimpresults()
    .省略空字符串()
    .split(Files.asCharSource(新文件(“您的文件路径”)、Charsets.UTF_8.read())
    );
    
    用正确的路径、正确的字符集、有无修剪来调味,如果你想留出空格和空字符串

    仅使用Java8 如果您不想使用番石榴,而只想使用香草Java,那么只需在Java8中执行类似的操作(再次道歉,未经测试):

    final Set lookupTable=
    Files.line(PATH.get(“您的文件路径”))
    .map(直线->直线分割(“,+”)
    .map(数组::流)
    .收集(toSet());
    
    使用Java<8
    如果Java<8,则使用常用的FileInputStream读取文件,然后使用String.split[]或StringTokenizer提取数组,最后将数组项添加到集合中

    我猜您还是将文件的行读入字符串,因此如果只计划一次查询,则将其拆分并将子字符串存储在一个集合中并不是最佳选择。

    如果您想了解性能差异的相关信息。简单地测量一下。这是给你的测试设置

    final int WORDS = 10000;
    final int SEARCHES = 1000000;
    
    Set<String> strSet = new TreeSet<String>();
    String strStr = "";
    int[] searches = new int[SEARCHES];
    Random randomGenerator = new Random();
    
    // filling set and string
    for(int i = 0; i < WORDS; i++){
        strSet.add(String.valueOf(i));
        strStr += "," + String.valueOf(i);
    }
    
    // creating searches
    for(int i = 0; i < SEARCHES; i++)
        searches[i] = randomGenerator.nextInt(WORDS);
    
    // measure set
    long startTime = System.currentTimeMillis();
    for(int i = 0; i < SEARCHES; i++)
        strSet.contains(String.valueOf(searches[i]));
    System.out.println("set result " + (System.currentTimeMillis() - startTime));
    
    // measure string
    startTime = System.currentTimeMillis();
    for(int i = 0; i < SEARCHES; i++)
        strStr.contains(String.valueOf(searches[i]));
    System.out.println("string result " + (System.currentTimeMillis() - startTime));
    
    final int WORDS=10000;
    最终整数搜索=1000000;
    Set strSet=new TreeSet();
    字符串strStr=“”;
    int[]searches=新int[searches];
    Random randomGenerator=新的Random();
    //填充装置和字符串
    for(int i=0;i
    对我来说,输出是一个有意义的证据,证明您应该使用
    集合

    设置结果350
    字符串结果14197


    如果给定的单词没有comas,Set应该占用更多的内存空间,但执行时间更少(可以通过简单的拆分完成)


    但我真正认为最好的方法是实验证明系统。currentTimeMillis()

    String.contains()
    将为
    “ava”
    返回true。我的预感是设置会更好。因为我猜它是用对象的散列来比较相等的。@kennytm如果在检查之前在输入字符串的开头和结尾加上逗号,它就不会这样做了。在
    字符串的
    集合中存储单个
    字符串的原因是什么?请阅读并提供
    不清楚你在问什么
    @BahramdunAdil你是否分析了你的程序并发现集合比较是一个热点?如果他只需要做一次查找,一个
    字符串。包含
    w
    final Set<String> lookupTable =
        Files.lines(Paths.get("YOUR_FILE_PATH"))
          .map(line -> line.split(",+"))
          .map(Arrays::stream)
          .collect(toSet());
    
    final int WORDS = 10000;
    final int SEARCHES = 1000000;
    
    Set<String> strSet = new TreeSet<String>();
    String strStr = "";
    int[] searches = new int[SEARCHES];
    Random randomGenerator = new Random();
    
    // filling set and string
    for(int i = 0; i < WORDS; i++){
        strSet.add(String.valueOf(i));
        strStr += "," + String.valueOf(i);
    }
    
    // creating searches
    for(int i = 0; i < SEARCHES; i++)
        searches[i] = randomGenerator.nextInt(WORDS);
    
    // measure set
    long startTime = System.currentTimeMillis();
    for(int i = 0; i < SEARCHES; i++)
        strSet.contains(String.valueOf(searches[i]));
    System.out.println("set result " + (System.currentTimeMillis() - startTime));
    
    // measure string
    startTime = System.currentTimeMillis();
    for(int i = 0; i < SEARCHES; i++)
        strStr.contains(String.valueOf(searches[i]));
    System.out.println("string result " + (System.currentTimeMillis() - startTime));