【问题标题】:Implementing comparable java实现可比较的java
【发布时间】:2016-02-07 17:49:56
【问题描述】:

我正在尝试使用可比较的界面按日期对用户输入的任务和日期列表进行排序。我在外部 .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新手,所以请耐心等待!谢谢!

【问题讨论】:

  • 您的目标是对文件中的任务进行排序还是仅仅为了将它们排序输出给用户?
  • 您确定当前版本的代码正在擦除文件吗?特别是你能仔细检查BufferedWriter bw = new BufferedWriter(new FileWriter(fileName, true));方法中sortList()的行吗?
  • 我只想在用户选择案例 3 时对任务进行排序。我想它不必在实际文件中对它们进行排序,只需将它们排序返回
  • 选择案例3时sortList方法正在删除我的.txt文件中的内容

标签: java compare comparable


【解决方案1】:

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

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 放到底部的最简单方法是更改​​ DueDate 类中的 compareTo 方法:

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

希望这会有所帮助(:

【讨论】:

  • 太棒了,这很好用!我只是注意到所有内容的两个副本,感谢您的更新。我仍然没有得到的一件事是,当我选择案例 3(sortlist 方法)时,它正在对任务进行排序,但直到我再次选择案例 1 才显示出来。我怎么会得到它,所以当我排序时它会显示出来
  • @Rassisland 编辑了我的答案:)
  • @Rassisland 没问题 :) 如果它解决了您的问题并且您不再寻找其他答案,如果您能接受它会很好:)
  • 没问题,不过还有一个问题!对于没有添加任何截止日期的任务,是否有一种相当简单的方法可以转到任务列表的底部?
  • @Rassisland 那么,如果你添加它们或者对它们进行排序,它们应该放到底部吗?
猜你喜欢
  • 2011-04-12
  • 1970-01-01
  • 2021-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-18
  • 2023-03-19
相关资源
最近更新 更多