2016-01-18 2 views
3

Мне нужно иметь ArrayList of ArrayList<Integer>, который, если индекс 0 имеет {1,4}, тогда индексы 1 и 4 также должны иметь 0 в своем списке. И наоборот, если 1 исключен из списка индекса 0, то индекс 1 также должен удалить 0 из его списка.Как убедиться, что список имеет определенные значения?

Нечто подобное, если john дружит с mark и elizabeth затем отметьте и элизабет иметь список своих друзей плюс john в их списке.

Любое предложение? Это не обязательно ArrayList, это только моя догадка.

+3

Для «брака» попробуйте использовать HashMap. – finnrayment

+0

https://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html – finnrayment

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

Thats your person setup! Теперь вам нужно начать использовать вновь созданных людей!

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

Выход: (отформатированный для Stack биржи)

John Doe Друзья:
* Jane Doe
Jane Doe Друзья:
* John Doe
* Dane Doe
Друзья Dane Doe:
* Jane Doe

(Лучше) реализация с использованием HashMap и UUID.

При необходимости необходимо изменить/сформировать класс Person. Единственная причина, по которой name существует в предыдущей реализации, заключается в том, чтобы идентифицировать человека в HashMap. Проблема в этом состоит в том, что могут существовать два «Джона Смита». Добавление во втором Джоне будет перезаписано предыдущей итерацией. Поэтому вы должны изменить name в addFriend() и 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); 
     } 
    } 
} 

(Best) реализация с использованием 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

Мое мнение было бы:

  • Создать класс для Friendship проведения двух Person сек симметричным образом (с точки зрения equals() и hashCode()), т.е. new Friendship('Mark, 'Frank').equals(new Friendship('Frank', 'Mark'))
  • Создать класс Friendships, который управляет отношения:
    • Удерживать Set<Friendship>, набор всех существующих друзей
    • Предоставляет методы для добавления новых отношений и удаления отношения, когда даются как «концы» (это Set, так что это было бы эффективно)
    • Если вы также должны получить доступ к друзьям данного лица, добавить индекс лицом структура
      • данных будет Map<Person, Set<Friendship>>
      • Этот показатель должен был бы обновляться при каждом добавлении или удалении отношения

В основном речь идет о неориентированном графе, причем вершины - это лица и ребра, представляющие дружеские отношения. Мое представление графа выше эффективно использует набор ребер, представление в другом ответе использует список смежности.

Для любого более крупного проекта было бы неплохо прочитать представление графиков и, возможно, использовать существующую библиотеку графов.

+1

Но теперь вы представляете еще один класс, хотя он делегирует все дружеские отношения. Если бы @secret должен был создать, скажем, веб-сайт социальной сети, вы просто делегировали друг другу дружескую дружбу в одно сопоставление, противоположное отдельным сопоставлениям на человека. Хотя (возможно) более эффективная, ваша модель менее безопасна. – finnrayment

+0

@frayment Я признаю, что мой подход ближе к дизайну базы данных, чем OO. Я думаю, что и мой, и ваш подход будет схожи с точки зрения эффективности. Я хотел бы узнать больше о вашей заботе о безопасности (вы имеете в виду информационную безопасность или защиту от ошибок программирования?). –

+0

Я говорю об информационной безопасности. – finnrayment