为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 Map<String, T> 在 java 中创建递归树状数据结构?

如何使用 Map<String, T> 在 java 中创建递归树状数据结构?

叮当猫咪 2022-06-23 16:49:41
在尝试创建遵循模式的数据结构时,我有一个思维障碍:Map<String, T>是一个主要的构建块,并且T是Map<String, T>或作为终端运营商List<String>。是否可以在 中构建任何类似的东西Java,这个想法来自类似F#或类似的函数Haskell式语言。我搜索SO但到目前为止找不到任何符合我的想法的Java.
查看完整描述

4 回答

?
红颜莎娜

TA贡献1842条经验 获得超13个赞

是的:你可以这样做:


public abstract class T {

...

}

public class NonTerminal extends T {

    private Map<String,T> map = new HashMap<>();

...

}

public class Terminal extends T {

    private List<String> list;

---

}


查看完整回答
反对 回复 2022-06-23
?
潇湘沐

TA贡献1816条经验 获得超6个赞

您可以只使用一个Map<String, KeyOrValue>值可以是具有两个实现的标记接口


interface KeyOrValue {}


class Key implements KeyOrValue {

    private String key;

}


class Value implements KeyOrValue {

    private List<String> values;

}

然后,您可以创建一个查找方法,该方法递归调用自身,然后在到达末尾时返回该值:


private final Map<String, KeyOrValue> map = ...


public List<String> getValues(String key) {

    KeyOrValue keyOrValue = map.get(key);

    if(keyOrValue instanceof Key) {

        // is a key, so use recursion to get the value

        key = ((Key) keyOrValue).key;

        return getValues(key);

    } else if(keyOrValue instanceof Value) {

        // is a value, so just return the value it holds

        return ((Value) keyOrValue).values;

    } else {

        // no mapping was found for "key"

        return null;

    }

}

你也可以在没有递归的情况下做同样的事情:


public List<String> getValues(String key) {

    KeyOrValue keyOrValue;

    List<String> values = null;

    do {

        keyOrValue = map.get(key);

        if(keyOrValue instanceof Key) {

            // is a key, so iterate further

            key = ((Key) keyOrValue).key;

        } else if(keyOrValue instanceof Value) {

            // is a value, so get the values out and set the key to null to break the loop

            values = ((Value) keyOrValue).values;

            key = null;

        }

    } while(key != null);


    // return the values, may be null due to nothing being found

    return values;

}

虽然实际上并不需要标记接口,但如果您只使用Map<String, Object>值可能是 aString或 a 的地方,您可以获得相同的结果List<String>,然后instanceof检查也必须进行调整,但我喜欢这种方法interface更多


查看完整回答
反对 回复 2022-06-23
?
jeck猫

TA贡献1909条经验 获得超7个赞

在 Java 中重新创建函数式编程的东西并不是一个好主意(至少在 Java 8 中不是,我不知道 Java 11)。


你可以这样做:


class EitherMapOrList {

    private Map<String, EitherMapOrList> map;

    private List<String> list;


    public EitherMapOrList(Map<String, EitherMapOrList> map) {

        this.map = map;

    }


    public EitherMapOrList(List<String> list) {

        this.list = list;

    }

    // you can remove the optionals here and use null directly.

    public Optional<Map<String, EitherMapOrList>> getMap() {

        return Optional.ofNullable(map);

    }


    public Optional<List<String>> getList() {

        return Optional.ofNullable(list);

    }

}

然后创建一个Map<String, EitherMapOrList>.


但我想在 Java 中使用这个东西会很痛苦。


查看完整回答
反对 回复 2022-06-23
?
明月笑刀无情

TA贡献1828条经验 获得超4个赞

如果你想翻译haskell


data Map a = Branch { key :: String, value :: a, left :: Map a, right :: Map a} | MapNul

到java你可以去:


class Map<T> {

    String key;

    T value;

    Map<T> left;

    Map<T> right;

MapNul你在java中不需要,因为你可以使用null它来代替它。


查看完整回答
反对 回复 2022-06-23
  • 4 回答
  • 0 关注
  • 355 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号