【问题标题】:String.contains behaving oddly with ArrayListString.contains 与 ArrayList 的行为异常
【发布时间】:2013-10-22 13:27:30
【问题描述】:

已解决。答案是替换

    for (int i = 0; i < results.size(); i++)
    {
        lowerField = results.get(i)[2].toLowerCase();

        if(lowerField.equals(search));
        {
            finalResults.add(results.get(i));
        }
    }

            for(String[] searchItems : results) 
            {
                lowerField = searchItems[2].toLowerCase();
                if(lowerField.equals(search)) 
                { // or lowerField.contains(search)
                    finalResults.add(searchItems);
                }
            }

似乎,由于某种原因,原始的 add(results.get(i)) 语句在某处混淆了某些东西,而 add(searchItems) 语句运行良好。

为了帮助其他有类似问题的人,请帮助我清理并澄清这个问题,使其符合适当的标准,以便它可以帮助其他人。

正确的工作代码以匹配原始问题中的示例:

public static ArrayList<String[]> searchLog(ArrayList<String> searchMe, String action)
{
    //ArrayList full of String arrays to break up and hold each line of the passed ArrayList
    ArrayList<String[]> results = new ArrayList<String[]>();
    //Same structure as above, intended to hold the lines matching the user's search criteria
    ArrayList<String[]> finalResults = new ArrayList<String[]>();
    //String variable used to hold the current field we're searching "toLowerCase"
    String lowerField = null;

    //For each string in the input ArrayList...
    for (String str : searchMe)
    {
        //Add each line (after splitting it into an array) to the "results" ArrayList
        results.add(str.split("~"));
    }

    //If the user chose to search on "Partner ID"
    if (action.equals("ptnr"))
    {
        //Print line with criteria and search field
        System.out.println("Searching on Partner ID for " + search + "....");

        //For each line (string array) in the "results" ArrayList
        for(String[] searchItems : results) 
        {
            //Set "lowerField" equal to the current line (string array) sub 1 where Partner ID is located, and set it toLowerCase
            lowerField = searchItems[1].toLowerCase();
            //If the cell we're searching contains the user's search criteria
            if(lowerField.contains(search)) 
            { 
                //Then add the whole line to the finalResults ArrayList that we will return from this function.
                finalResults.add(searchItems);
            }
        }
    }
    return finalResults;
}

再次感谢您的帮助!

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~ 好的,我有一个函数应该通过 ArrayList 并搜索列表中每个数组的特定部分。找到匹配项后,该函数会将整个数组添加到第二个 ArrayList 中,其中包含搜索结果。

我还尝试简单地从原始 ArrayList 中删除与搜索条件不匹配的任何内容,以节省不必要的第二个内存,并以这种方式获得相同的错误结果。要遵循的功能:

注意:SEARCH 是一段用户输入(存储在公共静态“全局”中),在此处使用之前已在我的 Main 函数中设置为“toLowerCase”。

    public static ArrayList<String[]> searchLog(ArrayList<String> searchMe, String action)
{
    ArrayList<String[]> results = new ArrayList<String[]>();
    ArrayList<String[]> finalResults = new ArrayList<String[]>();

    String lowerField = null;

    for (String str : searchMe)
    {
        results.add(str.split("~"));
    }

    if (action.equals("ptnr"))
    {
        System.out.println("Searching on Partner ID for " + search + "....");
        for (int i = 0; i < results.size()-1; i++)
        {
            lowerField = results.get(i)[1].toLowerCase();

            if(lowerField.equals(search))
            {
                //System.out.println("one added");
                finalResults.add(results.get(i));
            }
        }
    }

    return finalResults;
}

我尝试使用 lowerField.equals(search)、lowerField.contains(search) 和 lowerField.matches(search) 来包含它们的几个变体和字符串操作。

我的理想结果是使用“包含”,因为用户可以搜索的“时间戳”不切实际,并且包含的​​信息不仅仅是他们可以实际搜索的日期和时间。

现在是我的结果。

当我运行该函数并在“ptnr”上搜索时,我的结果是正确的。当我搜索其他两个中的任何一个时,我的结果返回正确的条目数(当我有一个 println 指示不匹配的条目已被删除时,包括正确的 REMOVED 数)但保留的条目和显示的是一个混合包不匹配的行以及匹配在一起。同样,打印出来的 NUMBER 行是正确的,但这些行本身并不是唯一匹配的行。

这是调用searchLog()的函数:

if(srv)
        {
            System.out.println("");
            System.out.println("============================= SEARCH RESULTS ===================================");
            System.out.println("");

            ArrayList<String[]> results = searchLog(line, "ptnr");

            for (int x = 0; x < results.size(); x++)
                System.out.println(results.get(x)[0] + " " + results.get(x)[1] + " " + results.get(x)[2] + " " + results.get(x)[3] + " " + results.get(x)[4] + " ms." );

            System.out.println("");
            System.out.println("============================= END SEARCH RESULTS ===================================");
            System.out.println("");
        }

在上面,“line”是我正在搜索的 ArrayList,“if”块中的“srv”是由用户输入设置的全局布尔值。所有这些目前都在工作,只是搜索和过滤器本身没有。

在此先感谢各位,如果您需要更多信息,请告诉我!

编辑:是的,我知道我使用了冒泡排序......让燃烧开始哈哈,但已经有一段时间了,这是一个新工作的时间敏感工具。在运行此实用程序的服务器上,处理的数据量最少(每次运行 300 行),气泡仍然在光标闪烁的情况下完成其目标。 :)

编辑 2:示例输入数据:

2013-10-15 08:28:31,514~stQAEFV~establishAgreementSummary~2~5234 ms.
2013-10-15 08:28:22,442~sgFASTOL~retrieveParty~2~1776 ms.
2013-10-15 08:27:37,333~sfRPDesktop~modifyParty~2~1744 ms.
2013-10-15 08:28:14,719~sgITL~retrieveParty~2~1702 ms.
2013-10-15 08:28:27,755~sgFASTOL~establishParty~2~1682 ms.
2013-10-15 08:28:39,677~sfRPDesktop~retrieveParty~2~1679 ms.
2013-10-15 08:27:55,768~sgBLD~searchAgreementSummary~2~1495 ms.
2013-10-15 08:27:46,272~sgCSCWB~searchAgreementSummary~1~1402 ms.
2013-10-15 08:27:49,660~sfRPDesktop~retrieveParty~2~1395 ms.
2013-10-15 08:27:39,547~sgHERYN~searchAgreementSummary~1~1341 ms.
2013-10-15 08:27:47,028~sgCSCWB~retrieveCustomerProfile~1~1323 ms.
2013-10-15 08:27:29,795~sgFASTOL~retrieveParty~2~1296 ms.
2013-10-15 08:27:44,520~sfRPDesktop~retrieveParty~2~1290 ms.
2013-10-15 08:28:04,398~sgFASTOL~retrieveParty~2~1284 ms.

在“ptnr”上搜索时输出正常工作,然后在时间戳上搜索“y”时输出(这不应该产生结果......)返回所有行:

============================= SEARCH RESULTS ===================================

Searching on Partner ID for sgfastol....
before sort
after sort
2013-10-15 08:28:22,442 sgFASTOL retrieveParty 2  1776 ms.
2013-10-15 08:28:27,755 sgFASTOL establishParty 2  1682 ms.
2013-10-15 08:27:29,795 sgFASTOL retrieveParty 2  1296 ms.
2013-10-15 08:28:04,398 sgFASTOL retrieveParty 2  1284 ms.





============================= SEARCH RESULTS ===================================

Searching on Timestamp for y....
before sort
after sort
2013-10-15 08:28:31,514 stQAEFV establishAgreementSummary 2  5234 ms.
2013-10-15 08:28:22,442 sgFASTOL retrieveParty 2  1776 ms.
2013-10-15 08:27:37,333 sfRPDesktop modifyParty 2  1744 ms.
2013-10-15 08:28:14,719 sgITL retrieveParty 2  1702 ms.
2013-10-15 08:28:27,755 sgFASTOL establishParty 2  1682 ms.
2013-10-15 08:28:39,677 sfRPDesktop retrieveParty 2  1679 ms.
2013-10-15 08:27:55,768 sgBLD searchAgreementSummary 2  1495 ms.
2013-10-15 08:27:46,272 sgCSCWB searchAgreementSummary 1  1402 ms.
2013-10-15 08:27:49,660 sfRPDesktop retrieveParty 2  1395 ms.
2013-10-15 08:27:39,547 sgHERYN searchAgreementSummary 1  1341 ms.
2013-10-15 08:27:47,028 sgCSCWB retrieveCustomerProfile 1  1323 ms.
2013-10-15 08:27:29,795 sgFASTOL retrieveParty 2  1296 ms.
2013-10-15 08:27:44,520 sfRPDesktop retrieveParty 2  1290 ms.
2013-10-15 08:28:04,398 sgFASTOL retrieveParty 2  1284 ms.

最后,我知道这很草率。我道歉。我实际上已经投入了三个小时,其中一个一直试图弄清楚这个搜索。这是一个用 Java 编写的 unix util(对 unix 不是很熟悉)(我是 .NET 开发人员),所以我有点不适应。一旦我让它发挥作用,就会进行清理。如果您愿意,这只是一个“草稿”,只是为了展示更大项目的可行性(或缺乏可行性)。不过感谢您的所有回复!遵循每个答案的具体 cmets。

-汤姆

【问题讨论】:

  • 您已经展示了很多代码,但并不清楚所有代码是否相关。为什么在迭代时省略finalResultsresults 的最后一个元素? (您的 for 循环的形式是 for (int i = 0; i &lt; size - 1; i++) 而不是 for (int i = 0; i &lt; size; i++)。)
  • 在 searchLog 方法中提供一个实际输入值的示例以及预期结果和实际结果将非常有帮助。如果您可以提供输入和搜索字符串的完整示例,我们可以帮助您解决这个问题。
  • @JonSkeet 修复了迭代器,不确定我在那里做什么。没有影响我的搜索结果。
  • @axiopisty 请查看我最近的编辑,感谢您的回复!

标签: java string search arraylist string-comparison


【解决方案1】:

即使对 OP 进行了两次编辑,仍然不清楚预期和实际结果是什么。也不清楚问题是什么。很难回答一个不清楚的、未提出的问题。但是根据示例代码,这里有一个示例测试程序,它可能会让您更接近您正在寻找的东西......也许?

import java.util.*;

public class Question19369420 {
    private static String search;

    public static void main(String[] args) {

        search = "sgfastol";

        List<String> input = new ArrayList<>();
        input.add("2013-10-15 08:28:31,514~stQAEFV~establishAgreementSummary~2~5234 ms.");
        input.add("2013-10-15 08:28:22,442~sgFASTOL~retrieveParty~2~1776 ms.");
        input.add("2013-10-15 08:27:37,333~sfRPDesktop~modifyParty~2~1744 ms.");
        input.add("2013-10-15 08:28:14,719~sgITL~retrieveParty~2~1702 ms.");
        input.add("2013-10-15 08:28:27,755~sgFASTOL~establishParty~2~1682 ms.");
        input.add("2013-10-15 08:28:39,677~sfRPDesktop~retrieveParty~2~1679 ms.");
        input.add("2013-10-15 08:27:55,768~sgBLD~searchAgreementSummary~2~1495 ms.");
        input.add("2013-10-15 08:27:46,272~sgCSCWB~searchAgreementSummary~1~1402 ms.");
        input.add("2013-10-15 08:27:49,660~sfRPDesktop~retrieveParty~2~1395 ms.");
        input.add("2013-10-15 08:27:39,547~sgHERYN~searchAgreementSummary~1~1341 ms.");
        input.add("2013-10-15 08:27:47,028~sgCSCWB~retrieveCustomerProfile~1~1323 ms.");
        input.add("2013-10-15 08:27:29,795~sgFASTOL~retrieveParty~2~1296 ms.");
        input.add("2013-10-15 08:27:44,520~sfRPDesktop~retrieveParty~2~1290 ms.");
        input.add("2013-10-15 08:28:04,398~sgFASTOL~retrieveParty~2~1284 ms.");

        String action = "ptnr";
        ArrayList<String[]> results = null;
        if ("time".equals(action)) {
            results = searchLogs(input, 0);
        } else if ("ptnr".equals(action)) {
            results = searchLogs(input, 1);
        } else if ("srv".equals(action)) {
            results = searchLogs(input, 2);
        }

        if (results != null) {
            System.out.println("before sort");
            print(results);
            Collections.sort(results, createComparator(4));
            System.out.println("after sort");
            print(results);
        }

    }

    public static Comparator<String[]> createComparator(final int field) {
        return new Comparator<String[]>() {
            @Override
            public int compare(String[] a, String[] b) {
                return a[field].compareTo(b[field]);
            }
        };
    }

    public static void print(List<String[]> list) {
        for (String[] item : list) {
            System.out.println(String.format("  %s %s %s %s %s ms.", item[0], item[1], item[2], item[3], item[4]));
        }
    }

    public static ArrayList<String[]> searchLogs(List<String> input, int index) {
        System.out.println("Searching on Partner ID for " + search + "....");
        ArrayList<String[]> results = new ArrayList<>();
        for (String str : input) {
            results.add(str.split("~"));
        }
        ArrayList<String[]> finalResults = new ArrayList<>();
        for (String[] searchItems : results) {
            String lowerField = searchItems[index].toLowerCase();
            if (lowerField.equals(search)) { // or lowerField.contains(search)
                finalResults.add(searchItems);
            }
        }
        return finalResults;
    }
}

这是运行程序的输出:

Searching on Partner ID for sgfastol....
before sort
  2013-10-15 08:28:22,442 sgFASTOL retrieveParty 2 1776 ms. ms.
  2013-10-15 08:28:27,755 sgFASTOL establishParty 2 1682 ms. ms.
  2013-10-15 08:27:29,795 sgFASTOL retrieveParty 2 1296 ms. ms.
  2013-10-15 08:28:04,398 sgFASTOL retrieveParty 2 1284 ms. ms.
after sort
  2013-10-15 08:28:04,398 sgFASTOL retrieveParty 2 1284 ms. ms.
  2013-10-15 08:27:29,795 sgFASTOL retrieveParty 2 1296 ms. ms.
  2013-10-15 08:28:27,755 sgFASTOL establishParty 2 1682 ms. ms.
  2013-10-15 08:28:22,442 sgFASTOL retrieveParty 2 1776 ms. ms.

【讨论】:

  • 我刚刚尝试了你的代码来迭代“结果”中的每个“searchItem”,它就像一个魅力......我不知道为什么会有所作为,但确实如此!感谢您的帮助和指点,我正在按照您现在的建议进行并简化功能! :D
  • 在我的第二次编辑中,“正确”的响应是只返回符合搜索条件的数据。实际响应是由于某种原因返回了所有数据。正如我在上面的评论中所说,它最终是一个简单的修复。我的“遍历、比较、添加是否相等”块不起作用,而您的块起作用。编辑我的原始帖子以显示正常运行的代码。
  • 排序不是问题。它只是作为一种奢侈品而存在,与我遇到的问题无关。对于造成的混淆,我深表歉意,并将其从我的问题中的原始(和工作)代码中删除。请参阅原始帖子以获取已清理、注释、工作的代码,以消除对我试图完成的任何混淆。谢谢。
【解决方案2】:

首先,您应该使用java.util.List 之类的接口而不是ArrayList,以使您的应用程序更加灵活。您的文字表明您正在使用某种时间戳,为什么您不使用 java.util.Date 或其他与时间有关的对象?

你为什么只是循环寻找results.size()-1?这会导致大量 results.size()-2 运行。设置循环结束的正确方法是i &lt; result.size()i &lt;= result.size()-1

您能否为您的错误提供一些输入和输出示例?

【讨论】:

  • 请参阅我的编辑以获取输入和输出示例。至于列表和日期的建议,责怪我的新手。我已经很长时间没有接触 Java 了,这是我第一次重新尝试这门语言。老实说,我将考虑使用 List 代替,因为我什至不知道功能差异。 Date 不实用,因为我正在处理的 Date 字段还包含一个唯一的进程 ID,该 ID 与我不想单独处理的日期相关联(不是唯一的,除了每个时间戳)。也不想为每种不同格式的日志样式设置不同的简单格式。
猜你喜欢
  • 2010-12-10
  • 1970-01-01
  • 2016-07-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-05
  • 2018-08-12
  • 2023-03-24
  • 1970-01-01
相关资源
最近更新 更多