I have a class Item, which uses a character as identifier.
public class Item {
private char identifier;
private Set<Character> predecessors;
private Set<Character> successors;
// Constructor, getters and setters...
}
I would like to be able to retrieve the paths, represented by the Path class, which contains a simple ordered list of Item :
public class Path {
private List<Item> items;
// Constructor, getters and setters
}
To store and manage my items and paths, I use a dedicated class. It contains two Set containing each of these types. I can retrieve a task using its identifier.
public class SimpleClass {
private Set<Item> items;
private Set<Path> paths;
// Constructor, getters and setters
public Optional<Item> getItemById(char identifier) {
/// ....
}
}
I would like to create a method to return a Set containing every Path but I can’t do it. A little help would be welcome. A small example to illustrate my point:
- D and E are the antecedents of G
- G is a successor of D and E
- A, B, D, G, J, K is a path
- A, C, F, H, J, K is a path
Update / Note: I am looking to build the paths through the set of items
Advertisement
Answer
A quick and dirty recursive algorithm. I just create the first map to speed up Item retrieval. See if it works, try to understand it and change it.
/**
* Build all paths
*/
public void buildPaths() {
Map<Character,Item> itemsByID=new HashMap<>();
for (Item i:items) {
itemsByID.put(i.getIdentifier(), i);
}
List<Item> starts=items.stream().filter(i->i.getPredecessors().isEmpty()).collect(Collectors.toList());
for (Item st:starts) {
Path p=new Path();
p.getItems().add(st);
buildPath(p,itemsByID);
}
}
/**
* Build the next step of the given path
* @param p
* @param itemsByID
*/
private void buildPath(Path p,Map<Character,Item> itemsByID) {
Item last=p.getItems().get(p.getItems().size()-1);
Set<Character> successors=last.getSuccessors();
// no successor, path is finished, add to collection
if (successors.isEmpty()) {
paths.add(p);
// one successor continue on same path
} else if (successors.size()==1){
p.getItems().add(itemsByID.get(successors.iterator().next()));
buildPath(p,itemsByID);
} else {
// multiple successors, create a new path for each branch
for (Character c:successors) {
Path p1=new Path();
p1.getItems().addAll(p.getItems());
p1.getItems().add(itemsByID.get(c));
buildPath(p1, itemsByID);
}
}
}
