如何确保列表具有某些必要的值?

时间:2016-01-18 07:13:00

标签: java

我需要一个ArrayList of ArrayList<Integer>,如果索引0有{1,4},那么索引1和4在它们的列表中也应该有0。反之亦然,如果从索引0的列表中删除1,则索引1也应从其列表中删除0。

如果johnmarkelizabeth的朋友,那么标记和伊丽莎白会在其列表中列出他们自己的朋友以及john

有什么建议吗?它不一定是ArrayList,这只是我的猜测。

2 个答案:

答案 0 :(得分:3)

(差)使用HashMap实现

首先,你想要一个代表你每个人的班级,以及一个包含他们朋友的列表:

public class Person {   
    String name;

    // For identification purposes.
    public Person(String name) {
        this.name = name;
    }

    HashMap<String, Person> friends = new HashMap<String, Person>();
}

现在您要将以下方法添加到类中,以允许您添加/删除朋友:

public void addFriend(Person person) {
    if (friends.get(person.name) == null) friends.put(person.name, person);
    person.friends.put(name, this);
}

public void removeFriend(Person person) {
    if (friends.get(person.name) != null) friends.remove(person.name);
    person.friends.remove(name);
}

// Only add this to test and see the list of friends.
public void printFriends() {
    System.out.println(name + "'s Friends:");
    for (Person p : friends.values()) {
        System.out.println("    " + p.name);
    }
}

这是你的人设置!现在你需要开始使用新创建的人员了!

public class PersonTest {
    public static void main(String[] args) {
        Person johndoe = new Person("John Doe");
        Person janedoe = new Person("Jane Doe");
        Person danedoe = new Person("Dane Doe");

        johndoe.addFriend(janedoe);
        janedoe.addFriend(danedoe);

        johndoe.printFriends();
        janedoe.printFriends();
        danedoe.printFriends();
    }
}

输出:(格式化为堆栈交换)

  

John Doe的朋友们:
      * Jane Doe
  Jane Doe的朋友们:
      * John Doe
      * Dane Doe
  Dane Doe的朋友们:
      * Jane Doe

使用HashMap和UUID的

(更好)实现。

您应该根据需要更改/整形Person课程。然而,在前面的实现中,name存在的唯一原因是能够识别HashMap中的人。这个的问题在于,可能存在两个约翰史密斯&#34; s。添加第二个John将覆盖上一次迭代。因此,您应该将nameaddFriend()中的removeFriend()更改为每人生成的UUID。

public class Person {
    String uuid = UUID.randomUUID().toString();

    HashMap<String, Person> friends = new HashMap<String, Person>();

    public void addFriend(Person person) {
        if (friends.get(person.uuid) == null) friends.put(person.uuid, person);
        person.friends.put(uuid, this);
    }

    public void removeFriend(Person person) {
        if (friends.get(person.uuid) != null) friends.remove(person.uuid);
        person.friends.remove(uuid);
    }

    public void printFriends() {
        System.out.println(uuid + "'s Friends:");
        for (Person p : friends.values()) {
            System.out.println("    " + p.uuid);
        }
    }
}
直接使用HashSet的

(最佳)实现

虽然上面两个实现工作*,但是它们会带来糟糕的编程习惯,并且会提高性能(虽然很小)。使用HashSet,完全无需包含UUID或任何其他形式的标识符,因为Set可以直接与进行通信,而无需一把钥匙。

*首次实施没有重复处理。

public class Person {
    String name;

    public Person(String name) {this.name = name;}

    Set<Person> friends = new HashSet<Person>();

    public void addFriend(Person person) {
        friends.add(person);
        person.friends.add(this);
    }

    public void removeFriend(Person person) {
        friends.remove(person);
        person.friends.remove(this);
    }

    public void printFriends() {
        System.out.println(name + "'s Friends:");
        for (Person p : friends) {
            System.out.println("    " + p.name);
        }
    }
}

PS:PersonTest类适用于所有3种实现。

答案 1 :(得分:1)

我的意思是:

  • Friendship创建一个以对称的方式保存两个Person的类(equals()hashCode()),即new Friendship('Mark, 'Frank').equals(new Friendship('Frank', 'Mark'))
  • 创建管理关系的类Friendships
    • 持有Set<Friendship>,一组所有现有友谊
    • 提供添加新关系和删除关系的方法,同时给出&#34;结束&#34; (它是Set,所以这些效率很高)
    • 如果您还需要访问给定人员的朋友,请按人员添加索引
      • 数据结构为Map<Person, Set<Friendship>>
      • 每当添加或删除关系时,都需要更新此索引

我们所谈论的基本上是一个无向图,顶点是代表友谊的人和边。我对上图的表示有效地使用了边集,另一个答案中的表示使用了主观列表。

对于任何更大的项目,阅读代表图表并使用现有的图表库可能是个好主意。