如何递归读取java映射
我有如下的Java地图。我想读取所有的值,其中键可以是其他键的值。在这里,我试图写一些反响的方法来阅读它,但没有运气。如果有人有经验,请向我解释如何递归读取java映射,java,dictionary,recursion,Java,Dictionary,Recursion,我有如下的Java地图。我想读取所有的值,其中键可以是其他键的值。在这里,我试图写一些反响的方法来阅读它,但没有运气。如果有人有经验,请向我解释 Map map= new HashMap(); map.put("a", "1"); map.put("b", "2"); map.put("c", "3"); map.put("1", "4"); map.put("4", "5"); 在上面的映射中,如果我将“a”作为键传递,我需要与a对应的所有值,即1,4,5,假设没有任何循环: private
Map map= new HashMap();
map.put("a", "1");
map.put("b", "2");
map.put("c", "3");
map.put("1", "4");
map.put("4", "5");
在上面的映射中,如果我将
“a”
作为键传递,我需要与a对应的所有值,即1,4,5
,假设没有任何循环:
private String mapRecursion(Map<String,String> map, String key) {
String s = map.get(key);
if (map.get(s) == null) {
return s;
}
return s + "," + mapRecursion(map, s);
}
私有字符串映射递归(映射映射,字符串键){
字符串s=map.get(key);
if(map.get=null){
返回s;
}
返回s+“,”+mapRecursion(map,s);
}
为了防止Java.lang.StackOverflowerError
,如果在映射中发生循环,您可以检查该值是否已在,并将continer(此处为集
)赋给该方法,而不让该方法自己创建它
static Set<String> getValues(Map<String, String> map, String key, Set<String> res) {
String val = map.get(key);
if (val != null && !res.contains(val)) {
res.add(val);
res.addAll(getValues(map, val, res));
}
return res;
}
//Use as
Set<String> res = getValues(map, "a", new HashSet<>());
System.out.println(res);
static Set getValues(映射图、字符串键、Set res){
字符串val=map.get(键);
如果(val!=null&&!res.contains(val)){
决议添加(val);
res.addAll(getValues(map,val,res));
}
返回res;
}
//用作
Set res=getValues(映射“a”,新的HashSet());
系统输出打印项次(res);
您可以通过从一个键开始并返回带有其值的方法调用来递归地导航映射
import java.util.*;
public class RecurseMap {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("a", "1");
map.put("b", "2");
map.put("c", "3");
map.put("1", "4");
map.put("4", "5");
map.put("5", "a"); // Circular reference!
navigate(map, "a");
}
public static <K, V> void navigate(Map<K, V> map, K key) {
navigate(map, key, new TreeSet<K>());
}
@SuppressWarnings("unchecked")
public static <K, V> void navigate(Map<K, V> map, K key, Set<K> visited) {
System.out.println(String.format("Current key: %s", key));
if (!visited.contains(key) && map.containsKey(key)) {
visited.add(key);
navigate(map, (K) map.get(key), visited);
}
}
}
请记住,方法签名应该是
或
,但我在上面使用了
来表示键、值关系
public static <K> void navigate(Map<K, K> map, K key) {
navigate(map, key, new TreeSet<K>());
}
public static <K> void navigate(Map<K, K> map, K key, Set<K> visited) {
System.out.println(String.format("Current key: %s", key));
if (!visited.contains(key) && map.containsKey(key)) {
visited.add(key);
navigate(map, (K) map.get(key), visited);
}
}
公共静态无效导航(地图地图,K键){
导航(地图、键、新树集());
}
公共静态无效导航(地图地图、K键、设置已访问){
System.out.println(String.format(“当前键:%s”,键));
如果(!visted.contains(键)&&map.containsKey(键)){
已访问。添加(键);
导航(地图,(K)地图。获取(键),访问);
}
}
在地图上行走 更新:您可以创建一个访问者类来评估地图键/值
import java.util.*;
public class RecurseMap {
private static interface Visitor<K> {
void visit(K key, K value, Map<K, K> map);
}
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("a", "1");
map.put("b", "2");
map.put("c", "3");
map.put("1", "4");
map.put("4", "5");
map.put("5", "a"); // Circular reference!
walkMap(map, "a", new Visitor<String>() {
@Override
public void visit(String key, String value, Map<String, String> mapRef) {
System.out.println(String.format("Current key: %s", key));
}
});
}
public static <K> void walkMap(Map<K, K> map, K key, Visitor<K> visitor) {
walkMap(map, key, visitor, new TreeSet<K>());
}
public static <K> void walkMap(Map<K, K> map, K key, Visitor<K> visitor, Set<K> visited) {
if (!visited.contains(key) && map.containsKey(key)) {
K value = map.get(key);
visitor.visit(key, value, map);
visited.add(key);
walkMap(map, value, visitor, visited);
}
}
}
import java.util.*;
公共类递归映射{
专用静态接口访问者{
无效访问(K键、K值、地图);
}
公共静态void main(字符串[]args){
Map Map=newhashmap();
地图放置(“a”、“1”);
地图放置(“b”、“2”);
地图放置(“c”、“3”);
地图放置(“1”、“4”);
地图放置(“4”、“5”);
map.put(“5”,“a”);//循环引用!
walkMap(地图,“a”,新访客(){
@凌驾
公共无效访问(字符串键、字符串值、映射映射参考){
System.out.println(String.format(“当前键:%s”,键));
}
});
}
公共静态虚空漫游地图(地图地图、K键、访客){
walkMap(地图、键、访问者、新树集());
}
公共静态无效漫游地图(地图地图地图、K键、访客、设置已访问){
如果(!visted.contains(键)&&map.containsKey(键)){
K值=map.get(键);
访客访问(关键、价值、地图);
已访问。添加(键);
walkMap(地图、价值、访客、访问);
}
}
}
您可以通过循环来实现这一点。你试过什么?你具体需要什么帮助?如果有一个无限循环怎么办?e、 g.1
转到2
,2
转到1
。然后您可以进行控制检查,查看您之前是否已读取该键。幸运的是,这不是无限循环。。但是,在mapNice和clean中,只有一样东西的键作为值的次数相同。你只需要小心无休止的递归(例如,如果你有{a=1,1=a}
)。是的,这看起来不错,但它只循环一个级别,我有一个包含多个级别键的映射让我以更好的方式解释。完美!这只需稍加修改就行了。谢谢你,罗斯兰!
import java.util.*;
public class RecurseMap {
private static interface Visitor<K> {
void visit(K key, K value, Map<K, K> map);
}
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("a", "1");
map.put("b", "2");
map.put("c", "3");
map.put("1", "4");
map.put("4", "5");
map.put("5", "a"); // Circular reference!
walkMap(map, "a", new Visitor<String>() {
@Override
public void visit(String key, String value, Map<String, String> mapRef) {
System.out.println(String.format("Current key: %s", key));
}
});
}
public static <K> void walkMap(Map<K, K> map, K key, Visitor<K> visitor) {
walkMap(map, key, visitor, new TreeSet<K>());
}
public static <K> void walkMap(Map<K, K> map, K key, Visitor<K> visitor, Set<K> visited) {
if (!visited.contains(key) && map.containsKey(key)) {
K value = map.get(key);
visitor.visit(key, value, map);
visited.add(key);
walkMap(map, value, visitor, visited);
}
}
}