0

I am just finishing up a project where we have to sort an ArrayList of objects from files by different sorting fields. Everything runs fine but I am running into one bug. When I run the code, the file objects are printed out in their original order, and no sorting is done.

I am pretty sure the bug is the instance variable I use in my collection class is not being changed after the sorting is done, but I do not know how to fix this.

Here is my Client class:

static int bpCount;
static String gene;
static int year;
static String yearString;
static String definition;
static String definitionString;
static String origin;
static String s;

public static void main(String[] args) throws FileNotFoundException{


    ArrayList<VirusObject> virusList = new ArrayList<VirusObject>();
    VirusCollection viruses = new VirusCollection(virusList);

    String folderName = "virusfiles";
    Scanner in = new Scanner(System.in);

    System.out.println("Hello user, this program you are about to use will sort and filter a large selection of virus files that contain various virus genre");

    System.out.println("Do you want to load a directory or file?");

    String userInput = in.nextLine();

    if(userInput.equals("file")){

        openViruses(virusList, folderName);

    }

    Scanner userIn = new Scanner(System.in);

    System.out.println("The current commands are sort, filter, and quit. Choose your commmand: ");

    String input = userIn.nextLine();

    if(input.equals("sort")){
        Scanner userInput3 = new Scanner(System.in);
        System.out.println("The current sorting methods are definition, reference, origin, year, and gene. Choose your sort: ");
        String sort = userInput3.nextLine();

        if(sort.equals("definition")){ //runs sort on temporary array, then runs print method

            viruses.sortDef();
            viruses.printViruses();

        }
        if(sort.equals("reference")){

            viruses.sortRef();
            viruses.printViruses();

        }
        if(sort.equals("origin")){

            viruses.sortOrg();
            viruses.printViruses();

        }
        if(sort.equals("year")){

            viruses.sortYr();
            viruses.printViruses();

        }
        if(sort.equals("gene")){

            viruses.sortGn();
            viruses.printViruses();

        }

        if(sort.equals("quit")){
            System.out.println("Have a good day buddy");
            return;

        }
    }

    if(input.equals("filter")){
        Scanner userInput2 = new Scanner(System.in);
        System.out.println("The current filters are definition, reference, origin, year, and gene. Choose your filter: ");
        String filter = userInput2.nextLine();

        if(filter.equals("definition")){

            System.out.println("What definition do you want to filter out?");
            String defFilter = userInput2.nextLine();
            viruses.printViruses();

        }
        if(filter.equals("reference")){

            System.out.println("Enter a reference or range: ");
            String refRange = userInput2.nextLine();
            viruses.filterYear(Range.parse(refRange));
            viruses.printViruses();

        }
        if(filter.equals("origin")){    

            System.out.println("What origin do you want to filter out?");
            String originFilter = userInput2.nextLine();
            viruses.filterDefinition(originFilter);
            viruses.printViruses();

        }
        if(filter.equals("year")){

            System.out.println("Enter a year or range: ");
            String yearRange = userInput2.nextLine();
            viruses.filterYear(Range.parse(yearRange));
            viruses.printViruses();

        }
        if(filter.equals("gene")){

            System.out.println("What gene do you want to filter out?");
            String geneFilter = userInput2.nextLine();
            viruses.filterDefinition(geneFilter);
            viruses
            .printViruses();

        }

        if(filter.equals("quit")){
            System.out.println("Have a good day buddy");
            return;

        }
    }
}

public static int openViruses(ArrayList<VirusObject> virusList, String folderName) throws FileNotFoundException {
    File folder = new File(folderName);
    File[] listOfFiles = folder.listFiles();
    int countOfFiles = 0;

    for (int i = 0; i < listOfFiles.length; i++) {
        if (listOfFiles[i].isFile()) {
            System.out.println("File " + listOfFiles[i].getName());
            parseFile(virusList, listOfFiles[i]);//parseFile provided by student!
            countOfFiles++;

        } else if (listOfFiles[i].isDirectory()) {
            System.out.println("Directory ignored: " + listOfFiles[i].getName());
        }
    }

    return countOfFiles;
}

public static void parseFile(ArrayList<VirusObject> virusList, File File1) throws FileNotFoundException{

    Scanner readFile = new Scanner(File1);

    while(readFile.hasNextLine()){

        String virusString = readFile.nextLine(); 
        Scanner in = new Scanner(virusString);

        if(virusString.contains("LOCUS")){

            in.next();
            in.next();
            bpCount = in.nextInt();
            in.next();

            gene = in.next();
            in.next();
            in.next();
            yearString = in.next();
            Scanner in2 = new Scanner(yearString);
            in2.useDelimiter("-");
            in2.next();
            in2.next();
            year = in2.nextInt();

        }

        if(virusString.contains("DEFINITION")){

            definitionString = in.nextLine();
            definition = definitionString.split("\\.")[0];


        }

        if(virusString.contains("ORIGIN")){
            if(virusString.contains("1"));
                origin = in.nextLine();

            }       
        }


    VirusObject Virus = new VirusObject(bpCount, gene, year, definition, origin);
    virusList.add(Virus);

    }
}

and here is the class where everything is sorted.

public ArrayList<VirusObject> virusList;

public VirusCollection(ArrayList<VirusObject> viruses){

    virusList = viruses; // placeholder to reach filters and sorts (temporary array)

}

public void sortDefinition(VirusObject[] viruses){

    int i;
    int j;

    for (j = 1; j < viruses.length; j++){
        VirusObject temp = viruses[j];
        i = j;

        while ( i> 0 && viruses[i - 1].getDefinition().compareTo(temp.getDefinition()) > 0){ // compareTo method used to compare string to 0
            viruses[i] = viruses[i - 1];
            --i;
        }

        viruses[i] = temp;
    }


}

public void sortReference(VirusObject[] viruses){

    int i;
    int j;

    for (j = 1; j < viruses.length; j++){
        VirusObject temp = viruses[j];
        i=j;


        while ( i > 0 && viruses[i - 1].getReference() > 0){
            viruses[i] = viruses[i - 1];
            --i;
        }

        viruses[i] = temp;
    }


}

public void sortYear(VirusObject[] viruses){

    int i;
    int j;

    for (j = 1; j < viruses.length; j++){
        VirusObject temp = viruses[j];
        i = j;

        while ( i > 0 && viruses[i - 1].getYear() > temp.getYear()){
            viruses[i] = viruses[i - 1];
            --i;
        }

        viruses[i] = temp;
    }


}

public void sortOrigin(VirusObject[] viruses){

    int i;
    int j;

    for (j = 1; j < viruses.length; j++){
        VirusObject temp = viruses[j];
        i = j;

        while ( i > 0 && viruses[i - 1].getOrigin().compareTo(temp.getOrigin()) > 0){
            viruses[i] = viruses[i - 1];
            --i;
        }

        viruses[i] = temp;
    }


}

public void sortGene(VirusObject[] viruses){

    int i;
    int j;

    for (j = 1; j < viruses.length; j++){
        VirusObject temp = viruses[j];
        i = j;

        while ( i > 0 && viruses[i - 1].getGene().compareTo(temp.getDefinition()) > 0){
            viruses[i] = viruses[i - 1];
            --i;
        }

        viruses[i] = temp;
    }
}

public void printViruses(){

    for (final VirusObject Virus : virusList){
        System.out.println(Virus.toString());
    }
}

public void sortDef(){

    VirusObject[] array = virusList.toArray(new VirusObject[virusList.size()]); // runs the sorting methods on a temporary array, makes it available to client as method
    sortDefinition(array);

}

public void sortRef(){

    VirusObject[] array = virusList.toArray(new VirusObject[virusList.size()]);
    sortReference(array);

}

public void sortYr(){

    VirusObject[] array = virusList.toArray(new VirusObject[virusList.size()]);
    sortYear(array);


}

public void sortOrg(){

    VirusObject[] array = virusList.toArray(new VirusObject[virusList.size()]);
    sortOrigin(array);

}

public void sortGn(){

    VirusObject[] array = virusList.toArray(new VirusObject[virusList.size()]);
    sortGene(array);

    }
}

Any help would be appreciated. Thank you

6
  • 1
    Why did you write your own sort and not use the builtin sort methods? Commented Mar 9, 2017 at 5:43
  • Start by creating an minimal reproducible example. You put up a ton of code that has NOTHING to do with sorting?! Commented Mar 9, 2017 at 5:45
  • @JimGarrison our teacher wanted us to write our own methods instead of using Collections.sort Commented Mar 9, 2017 at 5:45
  • @GhostCat I wasn't sure what was and wasn't useful to help solve the problem. The sorting methods are near the bottom of the second class Commented Mar 9, 2017 at 5:46
  • I saw them, but still: a lot of code means a lot of reading and scrolling. It would also help YOU if you could come up with an example that shows your problem without all the stuff that doesn't matter. Meaning: you don't need to fill an ArrayList from file to sort it. Make your main method define some example lists, sort them, and observe what happens. Commented Mar 9, 2017 at 5:59

3 Answers 3

1

I think the problem is that you call virusList.toArray(...), which creates a new array with the same values as the list, then you sort that array. You now have a sorted array, but the original list (virusList) hasn't been changed! You need to take your sorted result and use it to update virusList (convert it into an ArrayList or whatever).

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. Your explanation was clear and was easy to understand.
1

Here's your mistake!

When you call your sorting functions based on the user input, for example:

viruses.sortDef();

You are transferring all elements of your collection into an ArrayList, and then sorting that ArrayList instead.

This implements sorting on the the temporary ArrayList instance you created here:

    VirusObject[] array = virusList.toArray(new VirusObject[virusList.size()]); // runs the sorting methods on a temporary array, makes it available to client as method

And your actual collection instance remains unsorted because you have performed no operations on it!

1 Comment

Thanks for your help! Your explanation helped me understand what was wrong
0

In each of the methods that do the sorting, you copy references from the list to an array then sort the array. Then the printing uses the virusList to print. The sorted references are never set back into the virusList. There are many different ways you could solve this, including sorting the underlying list, but the minimal change to your code is probably:

public void sortDef(){

    VirusObject[] array = virusList.toArray(new VirusObject[virusList.size()]); // runs the sorting methods on a temporary   array, makes it available to client as method
    sortDefinition(array);
    virusList = new ArrayList<VirusObject>(Arrays.asList(array));
}

And make a similar change for all your sort methods.

1 Comment

This solved the problem, thank you for your help. I understand now!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.