-1

SOLVED. The answer was to replace

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

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

with

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

Seems that, for some reason, the original add(results.get(i)) statement was confusing something somewhere, whereas the add(searchItems) statement plays nicely.

To assist anyone else having a similar issue, please help me clean up and clarify this question to the proper standards so it can assist others.

CORRECT WORKING code to match sample in the original question:

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;
}

Thanks again for your help!

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ORIGINAL QUESTION~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Ok, I've got a function that's supposed to go through an ArrayList and search on a particular piece of each array in the list. Upon finding a match, the function adds that entire array to a second ArrayList full of the search results.

I ALSO tried simply removing anything that DID NOT match the search criteria from the original ArrayList to save the memory of having a second one unnecessarily and achieved the same incorrect result that way as well. Function to follow:

NOTE: SEARCH is a piece of user input (stored in a public static "global") that has already been set "toLowerCase" in my Main function before being used here.

    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;
}

I've tried using lowerField.equals(search), lowerField.contains(search), and lowerField.matches(search), to include several variations and string manipulations thereof.

My ideal outcome would be to use "contains," as the "timestamp" the user can search on is impractically specific and contains more info than just a date and time they can realistically search on.

Now for my results.

When I run the function and search on "ptnr," my results are correct. When I search on either of the other two, my results return the correct NUMBER of entries (to include the correct number of REMOVED when I had a println indicating that an entry that didn't match had been removed) but the entries that ARE retained and displayed are a mixed bag of non-matching lines as well as matches together. Again, the NUMBER of lines printed out is correct, but the lines themselves aren't the matching lines only.

This is the function that calls the 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("");
        }

Above, "line" is the ArrayList I'm searching through and "srv" in the "if" block is a global boolean set by user input. All of that is working currently, just not the search and filter itself.

Thanks in advance guys, and let me know if you need any more info!

EDIT: Yeah, I know I used a bubble sort... Let the flaming begin haha, but it's been a while and this is a time-sensitive util for a new job. On the server running this util, and with the minimal amount of data processed (300 lines per run), the bubble still accomplishes its goal in the blink of a cursor. :)

EDIT 2: Sample input data:

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.

Output when searched on "ptnr" working correctly, then output when searching on timestamp for "y" (which should not ever produce a result...) returning ALL rows:

============================= 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.

Finally, I know it's sloppy. I apologize. I've literally put three hours into it, one of which has been trying to figure out this search. It's a unix util (not very familiar with unix) written in Java (I'm a .NET dev), so I'm a little out of my element. Cleanup will take place once I get it functioning. This is simply a "rough draft" if you will, intended only to show the feasibility (or lack thereof) of a larger project. Thank you for all of your responses though! Specific comments to follow each answer.

-Tom

4

2 回答 2

0

即使在对 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.
于 2013-10-14T21:48:19.303 回答
0

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

你为什么只是循环results.size()-1?这会导致多次results.size()-2运行。设置循环结束的正确方法是i < result.size()i <= result.size()-1

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

于 2013-10-14T21:37:16.543 回答