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