Tôi có một số Map<String , String>
cho biết liên kết từ A đến B. Tôi muốn kết nối tất cả các tuyến đường có thể. ví dụ:java 8 kiểu chức năng của chuỗi liên kết
[A , B]
[B , C]
[C , D]
[E , F]
[F , G]
[H , I]
chí đầu ra
[A , B , C , D]
[E , F , G]
[H , I]
tôi thấy câu hỏi tương tự ở đây (nhưng không đáp ứng đầy đủ yêu cầu của tôi): https://stackoverflow.com/a/10176274/298430
Và đây là giải pháp của tôi:
public static <T> Set<List<T>> chainLinks(Map<T , T> map) {
Set<List<T>> resultSet = new HashSet<>();
map.forEach((from, to) -> {
if (!map.containsValue(from)) {
List<T> list = new ArrayList<>();
list.add(from);
list.addAll(inner(to, map));
resultSet.add(list);
}
});
return resultSet;
}
private static <T> List<T> inner(T from , Map<T , T> map) {
if (map.containsKey(from)) {
List<T> list = new ArrayList<>();
list.add(from);
list.addAll(inner(map.get(from), map));
return list;
} else {
List<T> end = new ArrayList<>();
end.add(from);
return end;
}
}
và trường hợp kiểm tra:
@Test
public void testChainLinks() {
Map<String , String> map = new HashMap<String , String>() {{
put("A" , "B");
put("B" , "C");
put("C" , "D");
put("E" , "F");
put("F" , "G");
put("H" , "I");
}};
Utils.chainLinks(map).forEach(list -> {
logger.info("list = {}" , list.stream().collect(Collectors.joining(" -> ")));
});
}
Nó hoạt động chính xác:
list = H -> I
list = E -> F -> G
list = A -> B -> C -> D
Nhưng tôi không thích giải pháp của tôi. Bởi vì tôi cảm thấy nó có thể được giải quyết theo một phong cách chức năng hơn. Tôi có thể cảm thấy mùi của stream.fold()
ở đây. Tôi đã cố gắng nhưng vô ích để chuyển đổi mã của tôi thành một phong cách chức năng thuần túy: có nghĩa là không tạo đối tượng trung gian ...
Có thể không? Mọi gợi ý đều biết ơn!
Xin lỗi, lỗi đánh máy. Ý tôi là Stream.reduce(). – smallufo
Hy vọng rằng đầu vào của bạn không có chu kỳ như 'put (" A "," B "); đặt ("B", "A"); '. Nếu không, các giải pháp được cung cấp sẽ không hoạt động. –
Có, tôi chắc chắn sẽ không có liên kết tuần hoàn. – smallufo