簡體   English   中英

如何使用Map在java中創建遞歸的樹狀數據結構 <String, T> ?

[英]How to create recursive tree-like data structure in java using Map<String, T>?

在嘗試創建遵循模式的數據結構時,我有一個思維模塊:

Map<String, T>是主要構建塊, TMap<String, T>或者是終端運算符List<String> 是否有可能在Java構建類似的東西,這個想法來自F#Haskell類的函數式語言。

我搜索了SO但到目前為止找不到任何符合我的想法的Java

是的:你可以這樣做:

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

在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中使用這個東西會很痛苦。

您可以只使用一個Map<String, KeyOrValue> ,其中值可以是具有兩個實現的標記接口

interface KeyOrValue {}

class Key implements KeyOrValue {
    private String key;
}

class Value implements KeyOrValue {
    private List<String> values;
}

然后,您可以創建一個recursivly調用自身的查找方法,然后在到達結尾時返回該值:

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> ,則可以得到相同的結果Map<String, Object>其中值可以是StringList<String> ,然后也必須調整instanceof檢查,但我更喜歡interface的方式

如果你想翻譯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;
} 

你不需要在java中使用MapNul ,因為你可以使用null而不是它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM