Как имплементировать tree в Java?
Проблема такова:
У меня есть три List:
List<String> origins; //10 элементов
List<String> destinations; //10 элементов
List<String> distances; //100 элементов
Задача моя соединить их всех в одну структуру. Структура такова:
1 -> 10 -> 10
То есть, каждый элемент в origins по отдельности должен быть связан со всеми 10 элементов из destinations. То бишь 1 origin - 10 destinations - (0,10) distances, 2 origin - 10 destinations - (10,20) distances, 3 origin - (20,30) destinations ...
Мне кажется это выглядит как Tree data structure, хотя я пробовал и Hashmap, но что-то не выходит.
Также вопрос, могу ли я использовать Lists как root или оно должно быть string, то есть одним значение?
root (List<String> origins)
|
List<String> destinations -0 | List<String> destinations -1| List<String> destinations -2... -10
|
List<String> distances (0,10)| List<String> distances (10,20)| List<String> distances (20,30) ...(90,100)
Вот что я попробовал сделать c помошью HashMap:
for ( Map.Entry<List<String>, Map<List<String>, List<String>>> entry : mapMap.entrySet()) {
List<String> key = entry.getKey(); //origins
Map<List<String>, List<String>> tab = entry.getValue(); //destinations and distances
// do something with key and/or tab
System.out.println(key.toString() + " " + tab.toString());
}
или
Map<List<String>,List<String>> map1 = new LinkedHashMap<>(); // ordered
Map<List<String>,Map<List<String>,List<String>>> map2 = new LinkedHashMap<>(); // ordered
map1.put(placesDestinations, placeDistances);
map2.put(placesOrigins, map1);
Оба результата, не выводят, так как мне нужно. Что происходит, это просто выводит первый лист origins, потом destinations, а затем все distances.
Ответы (1 шт):
Если строить дерево на каких-то простых структурах, то нужно использовать Map, так как дерево имеет одно ключевое значение и несколько дочерних. Поскольку в данном случае мы работает с String, это будет множество вида Map<String, Map<String, Map<String, Map<String, .... >>>>. Работать с такой структурой без какой-либо оболочки достаточно затруднительно.
Поскольку у нас конечное кол-во вариантов и дерево ограничено тремя уровнями, его можно построить так начиная с конца:
Map<String, List<String>> destinationMap = new LinkedHashMap<String, List<String>>();
for(int i = 0; i < destinations.size(); i++) {
destinationMap.put(destinations.get(i), distances.subList(i*10, i*10 + 10));
}
Map<String, Map<String, List<String>>> originsMap = new LinkedHashMap<String, Map<String, List<String>>>();
for(int i = 0; i < origins.size(); i++) {
originsMap.put(origins.get(i), destinationMap);
}
List<String> distanceList = originsMap.get("o5").get("d3");
Получается своеобразное дерево. Мы получим в качестве ключа String, а в качестве потомков Map<String, List<String>> и List<String> на втором и третьем уровне дерева соответственно.
Если бы дерево было больше, то задача бы усложнилась. Поэтому как по мне легче такие вещи строить на классах, которые включают друг друга:
class Node {
private String key;
private Node parent;
private List<Node> childs;
}
Ну или так, если делать полную и правильную реализацию: https://stackoverflow.com/questions/19330731/tree-implementation-in-java-root-parents-and-children
В данном случае достаточно будет такой структуры на классах:
public class Root {
private List<Origin> origins;
public Origin get(String name) {
for(Origin origin : origins)
if(origin.getName().equals(name))
return origin;
return null;
}
public Root(List<String> origins, List<String> destinations, List<String> distances ) {
List<Destination> destinationList = new ArrayList<Destination>();
for(int i = 0; i < destinations.size(); i++) {
destinationList.add(new Destination(destinations.get(i), distances.subList(i*10, i*10 + 10)));
}
List<Origin> originsList = new ArrayList<Origin>();
for(int i = 0; i < origins.size(); i++) {
originsList.add(new Origin(origins.get(i), destinationList));
}
this.origins = originsList;
}
public List<Origin> getOrigins() {
return origins;
}
public void setOrigins(List<Origin> origins) {
this.origins = origins;
}
}
public class Origin {
private String name;
private List<Destination> destinations;
public Destination get(String name) {
for(Destination destination : destinations)
if(destination.getName().equals(name))
return destination;
return null;
}
public Origin(String name, List<Destination> destinations) {
this.name = name;
this.destinations = destinations;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Destination> getDestinations() {
return destinations;
}
public void setDestinations(List<Destination> destinations) {
this.destinations = destinations;
}
}
public class Destination {
private String name;
private List<Distance> distances = new ArrayList<Distance>();
public Distance get(String name) {
for(Distance distance : distances)
if(distance.getName().equals(name))
return distance;
return null;
}
public Destination(String name, List<String> distances) {
this.name = name;
for(String el : distances)
this.distances.add(new Distance(el));
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Distance> getDistances() {
return distances;
}
public void setDistances(List<Distance> distances) {
this.distances = distances;
}
}
public class Distance {
private String name;
public Distance(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Main {
public static void main(String[] args) {
List<String> origins = Arrays.asList("o1", "o2", "o3", "o4", "o5", "o6", "o7", "o8", "o9", "o10");
List<String> destinations = Arrays.asList("d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10");
List<String> distances = Arrays.asList("1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12", "13", "14", "15", "16", "17", "18", "19", "20",
"21", "22", "23", "24", "25", "26", "27", "28", "29", "30",
"31", "32", "33", "34", "35", "36", "37", "38", "39", "40",
"41", "42", "43", "44", "45", "46", "47", "48", "49", "50",
"51", "52", "53", "54", "55", "56", "57", "58", "59", "60",
"61", "62", "63", "64", "65", "66", "67", "68", "69", "70",
"71", "72", "73", "74", "75", "76", "77", "78", "79", "80",
"81", "82", "83", "84", "85", "86", "87", "88", "89", "90",
"91", "92", "93", "94", "95", "96", "97", "98", "99", "100");
Root root = new Root(origins, destinations, distances);
List<Distance> distanceList = root.get("o2").get("d5").getDistances();
System.out.println(distanceList.toString());
}
}
