我试图使用可比较的界面按日期对用户输入的任务和日期列表进行排序。我将任务保存在外部.txt文件中,如果我访问正确的变量,会有些困惑。该程序可以编译,但是当我尝试对任务进行排序时,似乎会擦除文件的内容。这是我所拥有的:

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

    }


抱歉,需要额外的代码,但认为它可以帮助您了解我要执行的操作。任何建议都很好。我是Java新手,请耐心等待!谢谢!

最佳答案

问题是您的break中缺少switch语句,该语句在调用deleteTasks()之后正在调用sortList()方法。更改您的代码,它应该可以正常工作:

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


并且DueDate类的构造函数缺少enteredDueDate变量的分配,因为该参数被命名为dueDate而不是enteredDueDate。您应该将其更改为以下内容:

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


因为您当前正在将成员变量分配给它自己的值。
您还应该考虑更改sortList方法,尤其是BufferedWriter,否则每次调用该列表时,它都会复制该列表。像这样的灵魂做的事情:

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();




编辑:要打印出排序列表,您可以做一些事情。
最简单的方法可能是将showTaskList方法的调用附加到sortList方法的末尾,如下所示

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


或者您可以遍历ArrayList并像这样打印出来:

    //...
    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();
}




编辑2:最简单的方法是在排序时将所有Tasks和空的DueDate放到底部,是更改compareTo类中的DueDate方法:

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


只需对它取反,所有条目都将降序排列,并且DueDate为空的条目将位于列表的末尾(默认情况下,它将中继如何比较字符串)。
但是,如果您想在没有到期日的情况下使用Tasks,则会在sortList方法中遇到问题,因为split("\t")方法将仅返回长度为1的数组,并且if条件将失败。解决它的一种方法如下所示:

//...
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);
    }
}
//...


或更紧凑的版本(功能完全相同)

//...
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]));
}
//...


希望这可以帮助 (:

10-06 07:29