[英]How to create recursive tree-like data structure in java using Map<String, T>?
在嘗試創建遵循模式的數據結構時,我有一個思維模塊:
Map<String, T>
是主要構建塊, T
是Map<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>
其中值可以是String
或List<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.