Выбор структуры данных

 
 
 
Сообщения:30
Добрый день.

Не нашел в книге Шилдта примеров как реализовывать вложенные/многомерные коллекции.
Необходима структура в которой используется ключ значение.
Причем, значения в свою очередь будут являться ключами для других значений..
И так далее, всего 5 уровней.
Например, есть несколько нод, каждая содержит данные за несколько суток, каждые сутки содержат интервалы измерений по 5 минут, в каждом интервале данные с 12 процессоров, каждый из которых дает статистику по определенным параметрам.
Можно простой пример увидеть? Хотя бы двухэтажную структуру. Мне бы сам смысл понять
 
 
Сообщения:1240
import java.util.ArrayList;
import java.util.List;

class LevelOne {
    final int key;
    final List<LevelTwo> value;

    public LevelOne(int key, List<LevelTwo> value) {
        this.key = key;
        this.value = value;
    }
}
class LevelTwo {
    final String key;
    final List<LevelThree> value;

    public LevelTwo(String key, List<LevelThree> value) {
        this.key = key;
        this.value = value;
    }
}
class LevelThree {
    final String value;

    public LevelThree(String value) {
        this.value = value;
    }
}
public class Tst {
    public static void main(String[] args) {
        List<LevelThree> l3list = new ArrayList<>();
        l3list.add(new LevelThree("One"));
        l3list.add(new LevelThree("Two"));
        l3list.add(new LevelThree("Three"));

        List<LevelTwo> l2list = new ArrayList<>();
        l2list.add (new LevelTwo("Process One", l3list));
        l2list.add (new LevelTwo("Process Two", l3list));

        LevelOne lo = new LevelOne(1, l2list);

        List<LevelOne> l1list = new ArrayList<>();
        l1list.add(new LevelOne(1, l2list));
        l1list.add(new LevelOne(2, l2list));

        for (LevelOne l : l1list) {
            System.out.println("list1 = " + l.key);
            for (LevelTwo l2: l.value) {
                System.out.println("    list2 = " + l2.key);
                for (LevelThree l3: l2.value) {
                    System.out.println("         list3 = " + l3.value);
                }
            }
        }
    }
}
 
 
Сообщения:1240
Другой вариант:
import java.util.LinkedHashMap;
import java.util.Map;

public class Tst2 {
    public static void main(String[] args) {
        Map<Integer, Map<Integer, Map<Integer, String>>> gmap = new LinkedHashMap<>();
        for (int i = 0; i < 2; i++)  {
            LinkedHashMap<Integer, Map<Integer, String>> lmap2 = new LinkedHashMap<>();
            for (int j = 3; j < 5; j++) {
                LinkedHashMap<Integer, String> lmap3 = new LinkedHashMap<>();
                for (int k = 7; k < 9; k++) {
                    lmap3.put(k, "is " + i + " to " + j + " to " + k);
                }
                lmap2.put(j, lmap3);
            }
            gmap.put(i, lmap2);

        }

        // retrive;

        for (Map.Entry<Integer, Map<Integer, Map<Integer, String>>> me1 : gmap.entrySet()) {
            System.out.println("me1 key = " + me1.getKey());
            for (Map.Entry<Integer, Map<Integer, String>> me2 : me1.getValue().entrySet()) {
                System.out.println("    me2 key = " + me2.getKey());
                for (Map.Entry<Integer, String> me3 : me2.getValue().entrySet()) {
                    System.out.println("        me3 key = " + me3.getKey() + " and its value = " + me3.getValue());
                }
            }
        }

    }
}
 
 
Сообщения:9476
Похоже вроде на графы, не? Может стоит глянуть на JGraphT.
А еще - может не нужно вовсе делать иерархическую структуру. Просто хранить N списков каждый из которых отвечает либо за дни, либо за часы, либо за секундные отрезки. А высчитывать из секунд часы уже не сложно - и так определять где в списке часов искать нужную секунду.
Изменен:25 дек 2016 16:37
 
 
Сообщения:75
Quote:
Другой вариант:
Map<Integer, Map<Integer, Map<Integer, String>>> gmap = new LinkedHashMap<>();


Когда столкнулся с подобными конструкциями замучился отлаживать потом. Оооочень не удобно было.
Правда, там было еще хуже вариант.
Не рекомендую в общем =)

"Мы же профессионалы! Мы всегда делаем чуть больше, чем требуется!" (с)
 
 
Сообщения:1240
MuH3gPaB:

Когда столкнулся с подобными конструкциями замучился отлаживать потом. Оооочень не удобно было.
Правда, там было еще хуже вариант.
Не рекомендую в общем =)

Ага, при попытке отрефакторить можно застрелиться сразу. Но просто хотел показать возможный второй вариант.
 
 
Сообщения:1240
Третий вариант:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

class NodeData {
    final private int node;
    final private int day;
    final private int fiveMinuteNumber;
    final private String data;

    public NodeData(int node, int day, int fiveMinuteNumber, String data) {
        this.node = node;
        this.day = day;
        this.fiveMinuteNumber = fiveMinuteNumber;
        this.data = data;
    }

    public int getNode() {
        return node;
    }

    public int getDay() {
        return day;
    }

    public int getFiveMinuteNumber() {
        return fiveMinuteNumber;
    }

    public String getData() {
        return data;
    }
}
public class Tst3 {
    public static void main(String[] args) {
        Random r = new Random(System.nanoTime());
        List<NodeData> list = new ArrayList<>();

        for (int i = 0; i < 2; i++ ) {
            for (int j = 3; j < 6; j++) {
                for (int k = 7; k < 10; k++) {
                    NodeData nd = new NodeData(i, j, k, "At node " + i + " in day " + j +
                    " at " + k +"th five minute interval were happened that strange thing -> " + r.nextDouble());
                    list.add(nd);
                }
            }
        }

        // Отфильтруем, что случилось на ноде 1 за 5й день?
        List<NodeData> filteredData = list.stream().filter((x) -> (x.getNode() == 1 && x.getDay() == 5) )
                .collect(Collectors.toList());
        System.out.println(filteredData.size());
        for (NodeData nd : filteredData) {
            System.out.println(nd.getData());
        }
    }

}
 
 
Сообщения:2361
hard_link привет,

ответь скорее даже не мне, а самому себе на следующие вопросы:
  • Что есть вообще за сущности которые Вы назвали "процессор" и "нода".
  • Сколько у вас нод, планируется ли рост их числа.
  • Сколько измерений будет(хотя бы на вскидку) в каждом пятиминутном интервале для каждого "процессора".
  • Каким образом измерения будут доставляться из процессоров в структуру данных, которую Вы пытаетесь спроектировать? По отдельности, пачками, по какому транспорту?
  • Нужна ли абслютная точность при хранении измерений, если да то для каких юзкейсов.
  • За сколько дней нужно хранить историю, потребуется ли в будущем хранить историю за большие периоды.
  • Насколько эта статистика критична к потерям? Если JVM крешнится, или будет планово обновлятся то естесвенно вся статистика сгинет, что Вы будете отображать пользователю в этом случае?


Когда ответите на эти вопросы, я смогу Вам что-нибудь дельное посоветовать.
 
 
Сообщения:30
Великодушные, добрый день!

прошу прощения, что не отвечал долго! нет, я читал и делал, пытался и снова спотыкался...

Реально я бился над задачей около месяца, но вы мне помогли. на простом примере я понял как реализовать желаемое.
всех с новым годом!

Особенное спасибо за map Vurn'у. просто и доступно!

я реализовал такой мап в котором a -> b -> c -> d -> e


но есть попросы. после того как мы добавили в коллекцию (мап) put мы уже не можем изменить это?
в perl это птьфу просто. а тут все строго. можно ли внутри коллекции map изменять данные?
 
 
Сообщения:91
можно удалить или заменить другим объектом по заданному ключу
 
 
Сообщения:30
keekkenen:
можно удалить или заменить другим объектом по заданному ключу

про замену и про clear я знаю
но после того как мы положили коллекцию в другую коллекцию. мы можем изменять ее? или тот объект уже ушел (прилип к бытие) и его не изменить?
 
 
Сообщения:91
было бы предметнее.. показать что в чем находится и сказать какие именно изменения подразумеваются
 
 
Сообщения:45
hard_link:
про замену и про clear я знаю
но после того как мы положили коллекцию в другую коллекцию. мы можем изменять ее? или тот объект уже ушел (прилип к бытие) и его не изменить?


Можно.
import java.util.HashMap;
import java.util.Map;

public class Tst2 {
    public static void main(String[] args) {
        Map<Integer, Map<Integer, String>> gmap = new HashMap<>();
        for (int i = 0; i < 2; i++)  {
            Map<Integer, String> lmap2 = new HashMap<>();
            for (int j = 3; j < 5; j++) {
                lmap2.put(j, "" + i + " to " + j);
            }
            gmap.put(i, lmap2);

        }

        // retrive;
        for (Map.Entry<Integer, Map<Integer, String>> me1 : gmap.entrySet()) {
            System.out.println("me1 key = " + me1.getKey());
            for (Map.Entry<Integer,  String> me2 : me1.getValue().entrySet()) {
                System.out.println("    me2 key = " + me2.getKey() + " and value " + me2.getValue());
            }
        }
        System.out.println("retrive 1.0 ended...");
        // changing...
        Map<Integer, String> lm = gmap.get(1);
        lm.put(10, "There's new string!");
        lm.put(4, "There's new string #2!");

        // retrive 2.0
        for (Map.Entry<Integer, Map<Integer, String>> me1 : gmap.entrySet()) {
            System.out.println("me1 key = " + me1.getKey());
            for (Map.Entry<Integer,  String> me2 : me1.getValue().entrySet()) {
                System.out.println("    me2 key = " + me2.getKey() + " and value " + me2.getValue());
            }
        }
        System.out.println("retrive 2.0 ended...");


    }
}
Изменен:06 янв 2017 19:30
 
 
Сообщения:30
Действительно, легче пристрелиться..

Всем спасибо! Тему можно закрывать.

class Main{
    public static void main (String[] args){
        Block block  = new Block("out2112", "Disc-IOs");
        ArrayList<String> al = block.getBlockList();

        Map<String, Map<String, String>> lmap4 = new LinkedHashMap<>();
        Map<String, Map<String, Map<String, String>>> lmap3 = new LinkedHashMap<>();
        Map<String, Map<String, Map<String, Map<String, String>>>> lmap2 = new LinkedHashMap<>();
        Map<String, Map<String, Map<String, Map<String, Map<String, String>>>>> gmap = new LinkedHashMap<>();

        for (String lines : al){
            Params params = new Params(lines);

            Map<String, String> lmap5 = new LinkedHashMap<>();

            lmap5.put("cbt", params.cpuBusyTime);
            lmap4.put(params.cpuId, lmap5);
            lmap3.put(params.timeSlot, lmap4);
            lmap2.put(params.dateId, lmap3);
            gmap.put(params.nodeId, lmap2);
        }

        System.out.println("Host;Day;timeSlot;cpuId;param;value");
        for (Map.Entry<String, Map<String, Map<String, Map<String, Map<String, String>>>>> me1 : gmap.entrySet()){
            for (Map.Entry<String, Map<String, Map<String, Map<String, String>>>> me2 : me1.getValue().entrySet()){
                for (Map.Entry<String, Map<String, Map<String, String>>> me3 : me2.getValue().entrySet()){
                    for (Map.Entry<String, Map<String, String>> me4 : me3.getValue().entrySet()){
                        for (Map.Entry<String, String> me5 : me4.getValue().entrySet()){
                            System.out.println(me1.getKey() + ";" + me2.getKey() + ";" + me3.getKey() + ";" +
                                me4.getKey() + ";" + me5.getKey() + ";" + me5.getValue());
                        }
                    }
                }
            }
        }
    }
}


выхлоп. урезанный.
Quote:

Host;Day;timeSlot;cpuId;param;value
\MOSFE3;21 Dec 2016;00:00;0;cbt;23.81
\MOSFE3;21 Dec 2016;00:00;1;cbt;21.73
\MOSFE3;21 Dec 2016;00:00;2;cbt;19.02
\MOSFE3;21 Dec 2016;00:00;3;cbt;18.91
\MOSFE3;21 Dec 2016;00:00;4;cbt;19.69
\MOSFE3;21 Dec 2016;00:00;5;cbt;20.22
\MOSFE3;21 Dec 2016;00:00;6;cbt;19.90
\MOSFE3;21 Dec 2016;00:00;7;cbt;18.69
\MOSFE3;21 Dec 2016;00:00;8;cbt;19.06
\MOSFE3;21 Dec 2016;00:00;9;cbt;18.17
\MOSFE3;21 Dec 2016;00:00;10;cbt;19.83
\MOSFE3;21 Dec 2016;00:00;11;cbt;19.58
\MOSFE3;21 Dec 2016;00:05;0;cbt;23.81
\MOSFE3;21 Dec 2016;00:05;1;cbt;21.73
\MOSFE3;21 Dec 2016;00:05;2;cbt;19.02
\MOSFE3;21 Dec 2016;00:05;3;cbt;18.91
\MOSFE3;21 Dec 2016;00:05;4;cbt;19.69
\MOSFE3;21 Dec 2016;00:05;5;cbt;20.22
\MOSFE3;21 Dec 2016;00:05;6;cbt;19.90
\MOSFE3;21 Dec 2016;00:05;7;cbt;18.69
\MOSFE3;21 Dec 2016;00:05;8;cbt;19.06
\MOSFE3;21 Dec 2016;00:05;9;cbt;18.17
\MOSFE3;21 Dec 2016;00:05;10;cbt;19.83
\MOSFE3;21 Dec 2016;00:05;11;cbt;19.58
\MOSFE3;21 Dec 2016;00:10;0;cbt;23.81
\MOSFE3;21 Dec 2016;00:10;1;cbt;21.73
\MOSFE3;21 Dec 2016;00:10;2;cbt;19.02
\MOSFE3;21 Dec 2016;00:10;3;cbt;18.91
\MOSFE3;21 Dec 2016;00:10;4;cbt;19.69
\MOSFE3;21 Dec 2016;00:10;5;cbt;20.22
\MOSFE3;21 Dec 2016;00:10;6;cbt;19.90
\MOSFE3;21 Dec 2016;00:10;7;cbt;18.69
\MOSFE3;21 Dec 2016;00:10;8;cbt;19.06
\MOSFE3;21 Dec 2016;00:10;9;cbt;18.17
\MOSFE3;21 Dec 2016;00:10;10;cbt;19.83
\MOSFE3;21 Dec 2016;00:10;11;cbt;19.58


и так для каждой пятиминутки. зачем же тут день? это когда расширю приложение можно будет хоть за месяц делать и с разных узлов..
сейчас добавлю еще несколько параметров-значений для lmap5 и вообще все в шоколаде будет.
у меня только один вопрос - по философски сделано? является ли это java-way? или на процедурный костыль похоже?
 
 
Сообщения:142
обыкновенное дерево, деревом бы и делал

 
Модераторы:Нет
Сейчас эту тему просматривают:Нет