【问题标题】:ArrayList of objects sort using comparable使用可比较对象排序的 ArrayList
【发布时间】:2016-01-16 16:09:56
【问题描述】:

所以我正在处理通讯簿分配,但我一直坚持使用 Comparable 按姓氏对联系人进行排序。我正在尝试我们还没有真正学到的东西,比如对象的 ArrayLists、可比较和可序列化和可比较最让我困惑。

关于为什么联系人没有排序的任何提示?第二个问题,我想尝试将名字和姓氏的第一个字符设为大写,但我无法弄清楚,所以我在 toString 方法中将整个内容设为大写,任何想法如何只获取第一个字符上?

public class AddressBook implements Serializable{

private ArrayList<String> newBook = new ArrayList<String>();
private String dataFile;
private ArrayList<Contact> card =new ArrayList<Contact>(50);
private Contact[] contacts;
private int size = 0;
private int capacity = 0;
private String firstName;
private String lastName;


public static void main(String[] args) {
    AddressBook AB = new AddressBook();
    AB.addressBookMenu();
}


public void addressBookMenu() {
    Scanner scan = new Scanner(System.in);
    String option = "";

    System.out.println("PLEASE SELECT ONE OF THE FOLLOWING OPTIONS: ");
    System.out.println("\t add   --> Add a new contact ");
    System.out.println("\t find  --> Find a contact ");
    System.out.println("\t edit  --> Edit an existing contact ");
    System.out.println("\t view  --> View the current address book");
    System.out.println("\t save  --> Save the current address book");
    System.out.println("\t quit  --> quit");
    System.out.println();
    option = scan.nextLine();

    while(!(option.equalsIgnoreCase("quit"))) {
        Contact con = new Contact(firstName, lastName);
        if(option.equalsIgnoreCase("add")) {
            System.out.println("Enter First Name: ");
            String tempFirst = scan.nextLine();
            System.out.println("Enter Last Name: ");
            String tempLast = scan.nextLine();

            con.setFirstName(tempFirst);
            con.setLastName(tempLast); 
            card.add(con);  
            writeContact();
        }   

        //View address book
        if(option.equalsIgnoreCase("view")) {
            System.out.println("\tADDRESS BOOK" + "\n" +
                    "=============================");

            Collections.sort(card);
            con.getFullName();
            readContact();
        }

        System.out.println();
        System.out.println("PLEASE SELECT ONE OF THE FOLLOWING OPTIONS: ");
        System.out.println("\t add   --> Add a new contact ");
        System.out.println("\t find  --> Find a contact ");
        System.out.println("\t edit  --> Edit an existing contact ");
        System.out.println("\t view  --> View the current address book");
        System.out.println("\t save  --> Save the current address book");
        System.out.println("\t quit  --> quit");
        System.out.println();
        option = scan.nextLine();
    }
}

public void writeContact() {
    try (FileOutputStream out = new FileOutputStream("addressbook.txt")) {  
        ObjectOutputStream os = new ObjectOutputStream(out);

        os.writeObject(card);
        os.close();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

public void readContact() {
    try (FileInputStream in = new FileInputStream("addressbook.txt")) {
        ObjectInputStream is = new ObjectInputStream(in);
        ArrayList<Contact> card = (ArrayList<Contact>)is.readObject();

        for(Contact temp : card) {
            System.out.println(temp);
        }

        is.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}

联系类

public class Contact implements Comparable<Contact>, Serializable{

private String firstName;
private String lastName;
private String email;
private String phone;

public Contact() {
    firstName = "";
    lastName = "";
}
public Contact(String ln, String fn) {
    lastName = ln;
    firstName = fn;
}

public void setFirstName(String fn) {
    firstName = fn;
}
public void setLastName(String ln) {
    lastName = ln;
}
public void setFullName(String fn, String ln) {
    firstName = fn;
    lastName = ln;

}

public String getFirstName() {
    return firstName;
}
public String getLastName() {
    return lastName;
}
public String getFullName() {
    return lastName + firstName;
}

public String toString() {
    return 
            "FIRST NAME: " + getFirstName().substring(0).toUpperCase() + "\t" +
            "LAST NAME: " + getLastName().substring(0).toUpperCase() + "\n";            
}

@Override
public int compareTo(Contact nextContact) {
    return lastName.compareTo(nextContact.lastName);
}

}

【问题讨论】:

  • 请在每个帖子中只问 一个 问题,最好使用 简短 但完整的程序来演示问题。我怀疑问题是您的readContact() 忽略了您刚刚排序的集合的内容...
  • 我需要在 readContent 方法中对其进行排序吗?
  • stackoverflow.com/questions/1892765/… 回答您关于首字母大写的问题
  • 好吧,您当然不想在阅读时打印,除非联系人在写入之前进行了排序...您应该真正调试您的代码以了解发生了什么。
  • 谢谢 Jens 我会检查一下

标签: java sorting arraylist comparable


【解决方案1】:

关于为什么联系人没有排序的任何提示?

他们正在排序。但是你不打印排序的card。 您重新阅读readContact 中的联系人,然后将其打印出来,未排序。

你可能打算这样写:

if(option.equalsIgnoreCase("view")) {
    System.out.println("\tADDRESS BOOK" + "\n" +
            "=============================");

    readContact();
    Collections.sort(card);
    printContacts();
}

readContact 中更改这一行:

    ArrayList<Contact> card = (ArrayList<Contact>)is.readObject();

到这里:

    card = (ArrayList<Contact>)is.readObject();

并将打印从readContact移到它自己的方法:

void printContacts() {
    for(Contact temp : card) {
        System.out.println(temp);
    }
}

第二个问题,[...] 任何想法如何只获得第一个 char 上部?

当然,使用这样的辅助方法:

private String toTitleCase(String name) {
    return Character.toTitleCase(name.charAt(0)) + name.substring(1).toLowerCase();
}

【讨论】:

  • 我实际上尝试过Janos,我玩了一段时间。我只是按照你说的做了,它仍然打印未分类。
  • 嗯,当然,因为打印是在阅读之后。当一个方法有多个职责时,这是不好的。 readContact 应该只读取,打印应该用另一种方法,专门用于打印。查看我的更新答案
  • 啊,这是一个很好的选择,因为这样我可以对一个选项进行排序并在任何我想要的地方进行排序。谢谢亚诺斯!尽管我很抱歉,但我已经排除了另一个答案,但我希望我们可以除一个以上
【解决方案2】:

您的问题如下: 这段代码sn-p

Collections.sort(card);
con.getFullName();
readContact();

实际上是对您拥有的card 集合进行排序,然后调用readContact() 方法,该方法在其中创建一个本地card 集合,它会隐藏您在主程序中拥有的card 集合,并打印其联系人,因为它们之前已写入文件。他们没有得到排序。

解决方案是这样的:

if(option.equalsIgnoreCase("view")) {
    System.out.println("\tADDRESS BOOK" + "\n" +
                "=============================");

    con.getFullName(); // <------ ALSO, NOT QUITE SURE WHAT THIS IS FOR
    readContact();
}

public void readContact() {
    try (FileInputStream in = new FileInputStream("addressbook.txt")) {
        ObjectInputStream is = new ObjectInputStream(in);
        ArrayList<Contact> card = (ArrayList<Contact>)is.readObject();

        Collections.sort(card); // <----------- THIS ADDED

        for(Contact temp : card) {
            System.out.println(temp);
        }

        is.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

【讨论】:

  • Noodlez 做到了,谢谢!过去 2 小时一直在观看 Comparable 上的视频,以为我没有正确使用它。我对 Java 非常陌生,尤其是在 ArrayLists 中使用对象,所以就您指出的那一行而言……这是一个非常好的问题,哈哈。我认为它是剩下的代码,因为我一直在慢慢地将这个东西拼凑在一起,我首先确保我可以将一个对象添加到数组列表并将其打印出来,然后我创建了 readContact() 等等......我头疼,明天我再看你的描述,看看我能不能翻译成英文哈哈
猜你喜欢
  • 2018-05-02
  • 2015-07-05
  • 2017-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-17
  • 1970-01-01
相关资源
最近更新 更多