Как вы связываете предмет каждой Коллекции с предметом другого? - PullRequest
1 голос
/ 26 мая 2009

У меня есть два объекта Collection, я хочу связать каждый объект этих двух в удобочитаемом виде (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 одноместных номера.

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

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

Ответы [ 8 ]

1 голос
/ 26 мая 2009

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

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

0 голосов
/ 26 мая 2009

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

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;
0 голосов
/ 26 мая 2009

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

0 голосов
/ 26 мая 2009

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

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

0 голосов
/ 26 мая 2009

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

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

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

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

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);
    }
}
0 голосов
/ 26 мая 2009

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

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

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

// Коллекционные залы

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

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

0 голосов
/ 26 мая 2009

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

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

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

И создайте Список с ними.

0 голосов
/ 26 мая 2009

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

HashMap map = new HashMap();
for (int i=0; i<c1.Size(); i++) {
   map.put(c1[i], c2[i]);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...