简体   繁体   中英

Implementing comparable java

I am trying to sort a list of user entered tasks and dates by date using comparable interface. I have the tasks in a external .txt file and am a little confused if I am accessing the correct variables. The program compiles, but when I try to sort the tasks, it seems to erase the contents of the file. Here is what I have:

public class DueDate implements Comparable<DueDate>{

    public String addedTask = "";
    public String enteredDueDate;


    public DueDate(String addedTask, String dueDate){

        this.addedTask = addedTask;
        this.enteredDueDate = enteredDueDate;
    }

    public String toString(){
        return addedTask+"\t"+enteredDueDate+"\t";
    }

    @Override
    public int compareTo(DueDate o) {
        return this.enteredDueDate.compareTo(o.enteredDueDate);
    }
}

public class Main {

    public static String fileName = "/Users/eringray/Desktop/tasklistjava/src/javatask.txt";

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

        int menuItem = -1;
        while(menuItem != 0){
            menuItem = menu();
            switch (menuItem){
                case 1:
                    showTaskList();
                    break;
                case 2:
                    addTask();
                    break;
                case 3:
                    sortList();
                case 4:
                    deleteTasks();
                    break;
                case 0:
                    break;
                default:
                    System.out.println("Invalid Input");

            }
        }
    }



    static int menu(){
        int choice;
        Scanner sc = new Scanner(System.in);
        System.out.println("\n Task List Menu \n");
        System.out.println("0: Exit Menu");
        System.out.println("1: Show Tasks in List");
        System.out.println("2: Add Task to List");
        System.out.println("3: Sort Tasks by Due Date");
        System.out.println("4: Delete Tasks");
        System.out.println();
        System.out.println("Enter a choice: ");
            choice = sc.nextInt();
            return choice;
    }

    static void showTaskList(){
        System.out.println("\nTask List\n");
        try {
            Scanner inFile = new Scanner(new FileReader(fileName));
            String line;
            int number = 1;
            while(inFile.hasNextLine()){
                line = inFile.nextLine();
                System.out.println(number + ". " + line);
                ++number;
            }
            System.out.println();
            inFile.close();
        } catch (FileNotFoundException ioe) {
            System.out.println(ioe);
        }
    }

    static void addTask(){
        System.out.println("\nAdd Task\n");
        try {
            Scanner input = new Scanner(System.in);
            PrintWriter outFile = new PrintWriter(new FileWriter(fileName, true));
            System.out.println("Enter a Task: ");
            String addedTask = input.nextLine();
            System.out.println("Set Due Date for this Task(yyyy-mm-dd): ");
            String dueDate = input.nextLine();
            outFile.println(addedTask + "\t" + dueDate);
            outFile.close();
        } catch (IOException ioe) {
            System.out.println(ioe);
        }
    }
    static void sortList() throws IOException {
        System.out.println("\nSorted List\n");
        try {
            BufferedReader br = new BufferedReader(new FileReader(fileName));
            BufferedWriter bw = new BufferedWriter(new FileWriter(fileName, true));
            ArrayList<DueDate> tasks = new ArrayList<DueDate>();
            String line = "";
            while((line = br.readLine()) != null) {
                String[] values = line.split("\t");

                if(values.length == 2) {
                    String addedTask = values[0];
                    String enteredDueDate = values[1];

                    DueDate d = new DueDate(addedTask, enteredDueDate);

                    tasks.add(d);
                }
            }

            Collections.sort(tasks);

            for(int i = 0; i < tasks.size(); i++){
                DueDate date = tasks.get(i);
                String lineText = date.toString();
                bw.write(lineText);
                bw.newLine();
            }

            br.close();
            bw.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }


    }
    private static void deleteTasks(){
        PrintWriter writer = null;
        try {
            writer = new PrintWriter(fileName);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        assert writer != null;
        writer.print("");
        writer.close();
        }

    }

Sorry for the extra code, but thought it might help you see what I'm trying to do. Any suggestions would be great. I am new to Java, so please be patient with me! Thanks!

The problem is a missing break statement in your switch which is calling the deleteTasks() method after calling sortList() . Change your code to this and it should work fine:

int menuItem = -1;
while(menuItem != 0){
    menuItem = menu();
    switch (menuItem){
        case 1:
            showTaskList();
            break;
        case 2:
            addTask();
            break;
        case 3:
            sortList();
            break; //The missing break
        case 4:
            deleteTasks();
            break;
        case 0:
            break;
        default:
            System.out.println("Invalid Input");
    }
}

And the constructor of the DueDate class is missing the assignment of the enteredDueDate variable since the parameter was named dueDate and not enteredDueDate . You should change it to something like this:

public DueDate(String addedTask, String enteredDueDate){
    this.addedTask = addedTask;
    this.enteredDueDate = enteredDueDate;
}

since you are currently assigning the member variable to it's own value. You should also consider changing the sortList method, especially the BufferedWriter or it will duplicate the list each time you call it. Something like this sould do it:

BufferedReader br = new BufferedReader(new FileReader(fileName));
ArrayList<DueDate> tasks = new ArrayList<DueDate>();
String line = "";
while((line = br.readLine()) != null) {
    String[] values = line.split("\t");
    if(values.length == 2) {
        String addedTask = values[0];
        String enteredDueDate = values[1];
        DueDate d = new DueDate(addedTask, enteredDueDate);
        tasks.add(d);
    }
}
Collections.sort(tasks);
br.close();
//Changed it to not append but overwrite the old file so it only contains the sorted list
BufferedWriter bw = new BufferedWriter(new FileWriter(fileName, false));
for (DueDate date : tasks) {
    String lineText = date.toString();
    bw.write(lineText);
    bw.newLine();
}
bw.flush();
bw.close();

EDIT :To print the sorted list out there are a few things you could do. The easiest way would probably be to append a call of the showTaskList method to the end of the sortList method like this

    //...
    bw.flush();
    bw.close();
    showTaskList();
} catch (FileNotFoundE
    e.printStackTrace(
}

or you could loop through the ArrayList and print them out like this:

    //...
    bw.flush();
    bw.close();
    for (int i = 0; i < tasks.size(); i++) {
        DueDate dueDate = tasks.get(i);
        System.out.println(i+". "+dueDate.toString());
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

EDIT 2 : The easiest way to get all Tasks with empty DueDate to the bottom when sorting is to change the compareTo method in DueDate class:

@Override
public int compareTo(DueDate o) {
    return -this.enteredDueDate.compareTo(o.enteredDueDate);
}

Just negate it so all entries are sorted descending and those with empty DueDate will be at the end of the list (it relays on how strings are compared by default).
But if you want to use Tasks with no due date you'll run into a problem in your sortList method since the split("\\t") method will only return an array with length 1 and your if condition would fail. One way to solve it looks like this:

//...
while ((line = br.readLine()) != null) {
    String[] values = line.split("\t");
    //To ensure it's still valid data
    if (values.length >= 1 && values.length <= 2) {
        String addedTask = values[0];
        String enteredDueDate;
        //Check whether dueDate has a value or is empty
        if (values.length == 1)
            enteredDueDate = "";
        else
            enteredDueDate = values[1];
        DueDate d = new DueDate(addedTask, enteredDueDate);
        tasks.add(d);
    }
}
//...

or more compact version (does exactly the same thing)

//...
while ((line = br.readLine()) != null) {
    String[] values = line.split("\t");
    if (values.length >= 1 && values.length <= 2)
        tasks.add(new DueDate(values[0], values.length == 1 ? "" : values[1]));
}
//...

Hope this helps (:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM