Как вы связываете элемент каждой коллекции с элементом другой?

StackOverflow https://stackoverflow.com/questions/911023

  •  06-09-2019
  •  | 
  •  

Вопрос

У меня есть два объекта коллекции, я хочу связать каждый объект из этих двух доступным для чтения способом (HashMap, Объект, созданный специально, вы выбираете).

Я думал о двух циклах, один вложенный в другой, но, возможно, это хорошо известная проблема и у нее есть общепринятое решение...

Что делать, если количество объектов коллекции превысит два?

РЕДАКТИРОВАТЬ после комментария Джозефа Дейгла:Все предметы коллекции относятся к одному типу, это номера отелей, которые, как оказалось, можно забронировать при определенных условиях.

Collection<Room> roomsFromA = getRoomsFromA();
Collection<Room> roomsFromB = getRoomsFromB();
for(Room roomA : roomsFromA){
    for(Room roomB : roomsFromB){
        //add roomA and roomB to something, this is not important for what I need
        //the important part is how you handle the part before
        //especially if Collection objects number grows beyond two
    }
}

ПРАВКА 2:Я постараюсь объяснить лучше, извините за неясность вопроса.Следует примеру:Пользователь запрашивает двухместный и одноместный номер.В отеле есть 3 двухместных и 4 одноместных номера.

Мне нужно связать каждый "двухместный номер" с каждым "одноместным номером", это потому, что у каждого номера есть своя особенность, скажем, интернет, более приятный вид и так далее.Поэтому мне нужно предоставить пользователю все комбинации, чтобы он мог выбирать.

Это простой случай, в котором задействованы только две коллекции объектов Room, как вы справляетесь с проблемой, когда, скажем, и отель, и пользователь могут предлагать / запрашивать больше типов номеров?

Это было полезно?

Решение

То, что вы пытаетесь здесь сделать, это получить все возможные перестановки выбора X из набора Y.Это хорошо известная проблема в дискретной математике, и я думаю, что она просто называется Комбинаторной математикой.

Чтобы решить вашу проблему, вам нужно создать суперколлекцию, содержащую все ваши типы номеров.Если это массив или Список, вы можете затем использовать этот пример вычислить все возможные способы выбора X из множества Y.В примере будут приведены индексы из списка / массива.

Другие советы

Точно ли составлены коллекции?

HashMap map = new HashMap();
for (int i=0; i<c1.Size(); i++) {
   map.put(c1[i], c2[i]);
}

Ну, поскольку я не знаю, нужно ли вам будет искать оба из них, имея только один, хэш-карта не будет работать.

Я бы создал класс, который получает Пару..вроде того:

private static class Pair<K, T> {
    private K one;
    private T two;

    public Pair(K one, T two) {
        this.one = one;
        this.two = two;
    }

    /**
     * @return the one
     */
    public K getOne() {
        return one;
    }

    /**
     * @return the two
     */
    public T getTwo() {
        return two;
    }
} 

И составьте из них Список.

Ваш пример подразумевает, что возвращаемое значение из "roomsFromB" является вложенной коллекцией возвращаемого значения "roomsFromA", поэтому было бы более естественно смоделировать его таким образом:

class Room {
   public Collection<Room> getRoomsFromB { ... 
}

что затем позволило бы вам сделать :

//Комнаты для сбора

for (Room a: rooms)
{ 
   for(Room b a.getRoomsFromB){ ...

Конечно, это предполагает, что они моделируются иерархически.Если это не так, то это неуместно, но тогда вопрос, который вы задаете, как мне кажется, на самом деле заключается в том, как смоделировать отношения между ними, и вы еще не сделали это явным.

Вы могли бы пересмотреть, нужна ли вам именно эта логика.Вы вводите операцию O (n ^ 2), которая может быстро выйти из-под контроля.(Технически O(mn), но я предполагаю, что m и n примерно в одном и том же порядке.)

Есть ли другое решение вашей проблемы?Возможно, вы могли бы создать "набор", который включает в себя все A и все B, и тогда каждый объект в A и B мог бы вместо этого указывать на этот набор?

Я предполагаю , что:

  • Каждый элемент в collection 1 будет соответствовать одному элементу в collection 2
  • В коллекции имеют одинаковую размер
  • Коллекции могут быть упорядочены и порядок соответствует каждому элементу в обеих коллекциях

  1. Упорядочите обе коллекции (в одинаковом порядке) по свойству, которое идентифицирует каждый объект.
  2. Выполните итерацию по обеим коллекциям с помощью одного цикла, создайте объект relation и добавьте его в новую коллекцию.

Посмотрим, поможет ли это вам:

public static class Room {
    private int number;
    private String name;

    public Room(int number, String name) {
        super();
        this.number = number;
        this.name = name;
    }

    public int getNumber() {
        return number;
    }

    public String getName() {
        return name;
    }
}

public static class RoomRelation {
    private Room a;
    private Room b;

    public RoomRelation(Room a, Room b) {
        super();
        this.a = a;
        this.b = b;
    }

    public Room getA() {
        return a;
    }

    public Room getB() {
        return b;
    }

    @Override
    public String toString() {
        return a.getName() + "(" + a.getNumber() + ") " + b.getName() + "(" + b.getNumber() + ")";
    }
}

public static void main(String[] args) {

    List<Room> roomsFromA = new ArrayList<Room>();
    List<Room> roomsFromB = new ArrayList<Room>();

    roomsFromA.add(new Room(1,"Room A"));
    roomsFromA.add(new Room(2,"Room A"));

    roomsFromB.add(new Room(1,"Room B"));
    roomsFromB.add(new Room(2,"Room B"));

    Comparator<Room> c = new Comparator<Room>() {
        @Override
        public int compare(Room o1, Room o2) {
            return o1.getNumber() - o2.getNumber();
        } };

    Collections.sort(roomsFromA, c);
    Collections.sort(roomsFromB, c);

    List<RoomRelation> relations = new ArrayList<RoomRelation>();

    for (int i = 0; i < roomsFromA.size(); i++) {
        relations.add(new RoomRelation(roomsFromA.get(i), roomsFromB.get(i)));
    }

    for (RoomRelation roomRelation : relations) {
        System.out.println(roomRelation);
    }
}

Ваш вопрос совершенно неясен.Как я понимаю, вы хотите перечислить все комбинации комнат, за вычетом дубликатов.Вот нам некоторый код для создания 2d-массива всех комбинаций комнат.Для большего количества типов пространства вставьте еще один вложенный цикл.

Collection<Room> roomsFromA = getRoomsFromA();
Collection<Room> roomsFromB = getRoomsFromB();

Room[][] combinations = new Room[roomsFromA .size()][roomsFromB .size()];

int a = 0;
int b = 0;

for(Room roomA : roomsFromA){

   for(Room roomB : roomsFromB){
      combinations [a][b] = [roomA][roomB]; //Build up array
      b++; 
   }
   a++;
}

return combinations;

Это распространенная проблема.Это называется Декартово произведение.Если у вас есть две коллекции, как в вашем случае, я бы без колебаний использовал два вложенных цикла.В противном случае, смотрите этот вопрос.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top