电话簿编程 - TreeSet或HashSet

时间:2013-01-17 09:28:38

标签: java equals treeset

我有一个很好的问题 - 创建电话簿 - 包含联系人列表。 正如电话簿所说,

  1. 联系人应始终排序。(按名称)
  2. 可以明星标记 联系人,所以他们必须高于其余部分。(*联系人 按联系人创建时间排序)

    class PhoneBook{
    //require an always sorted d.s
    TreeSet<Contact> contacts = new TreeSet<Contact>();
    
    @Override
    public String toString() {
        return "PhoneBook [contacts=" + contacts + "]";
    }
    
    public boolean addContact(Contact contact){
        //validate before adding the contact.
        return contacts.add(contact);
    }
    

    }

    class Contact implements Comparable<Contact>{
    String name;
    int phoneNo;
    Date timeAdded;
    boolean starContact;
    
    
    
    public Contact(String name, int phoneNo, Date timeAdded, boolean starContact) {
        super();
        this.name = name;
        this.phoneNo = phoneNo;
        this.timeAdded = timeAdded;
        this.starContact = starContact;
    }
    
    
    
    @Override
    public int compareTo(Contact otherContact) {
        if(this.starContact && otherContact.starContact){
            return this.timeAdded.before(otherContact.timeAdded)?-1:1; //impossible to add 2 contacts at the same time
        }else if(this.starContact){
            return -1;
        }else if(otherContact.starContact){
            return 1;
        }else{
            //simple Contacts
            return this.name.compareTo(otherContact.name);
        }
    }
    
    
    
    
    
    
    @Override
    public String toString() {
        return "\nContact [name=" + name + ", timeAdded=" + timeAdded
                + ", starContact=" + starContact + "]";
    }
    
    
    }
    
  3. 测试代码

        public class MobilePhoneBookDemo {
    
    /**
     * @param args
     */
    public static void main(String[] args) {
    
        PhoneBook phoneBook = new PhoneBook();
    
        Contact frnd1 = new Contact("Z",56,new Date(),false);
        phoneBook.addContact(frnd1);
        Contact frnd2 = new Contact("A",3,new Date(),false);
        phoneBook.addContact(frnd2);
        Contact frnd3 = new Contact("C",30,new Date(),false);
        phoneBook.addContact(frnd3);
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Contact ta = new Contact("Ta", 5, new Date(), true);
        phoneBook.addContact(ta);
        Contact ma = new Contact("Ma", 31, new Date(), true);
        phoneBook.addContact(ma);
        Contact baba = new Contact("Baba", 300, new Date(), true);
        phoneBook.addContact(baba);
    
        //change the priority later for one of my friends.
        System.out.println(phoneBook);
        frnd1.starContact = true;
        System.out.println(phoneBook.contacts.contains(frnd1));
    
        if(phoneBook.contacts.remove(frnd1)){
            System.out.println("removed");
            phoneBook.contacts.add(frnd1);
        }
    
        System.out.println(phoneBook);
    }
    

    }

    面临的问题:

    1. 包含找不到条目,​​有什么不妥之处? 我确实尝试在Contact上放置一个equals和一个hashcode,显然,如果存在Comparator / Comparable,则只调用compare *。
    2. 在这里使用TreeSet是否公平,还是应该使用任何其他数据结构? 例如。 HashSet然后转换为TreeSet?
    3. contains()甚至不比较地图中的所有条目,只是与C,Ma和Ta条目进行比较。那是为什么?
    4. 根据订单质疑优先权。 我很欣赏所有答案,但这确实是一个完整的测试案例,所以请在提供答案之前尝试运行一次PhoneBook。非常感谢。

3 个答案:

答案 0 :(得分:4)

这一行:

return this.timeAdded.before(otherContact.timeAdded)?-1:1;

如果您将联系人与自身进行比较,

将永远不会返回0。因此,该集将无法找到具有contains()

的对象

答案 1 :(得分:1)

你让我在

  

联系人应始终排序。(按名称)

如果命令很重要,请使用TreeSet。元素存储在各种二叉搜索树中,这意味着它们默认排序。

另一方面,

HashSet不保证任何订单,排序甚至插入订单。


编辑 - 尝试以这种方式编写条件,更具可读性和更强大。条件的顺序是比较的优先顺序。

if(a != b){
    return a<b;
}

if(c != d) {
    return c<d;
}

//and so on.

return 0;

答案 2 :(得分:0)

解决方案很简单,首先删除,然后更改值并再次添加。 我首先评论修改,我也放入了修改过的compareTo(),因为它周围有很多混淆。

//frnd1.starContact = true;
    System.out.println("Entry present>"+phoneBook.contacts.contains(frnd1));

    if(phoneBook.contacts.remove(frnd1)){
        System.out.println("removed");
        frnd1.starContact = true;
        phoneBook.contacts.add(frnd1);
    }


@Override
public int compareTo(Contact otherContact) {
    if(otherContact.phoneNo == this.phoneNo){
        return 0;
    }
    if(this.starContact && otherContact.starContact){
        return this.timeAdded.before(otherContact.timeAdded)?-1:1; //impossible to add 2 contacts at the same time
    }else if(this.starContact){
        return -1;
    }else if(otherContact.starContact){
        return 1;
    }else{
        //simple Contacts
        return this.name.compareTo(otherContact.name);
    }
}