例如,给出如下地图: { "k1": { "k2": { "k3": { "k4": "v" } } }} 和字段列表[“k1”,“k2”,“k3”],我需要检索部分{“k4”:“v”}. 下面是我的java7风格的代码: // Ignore the map building code.Map map1 =
{ "k1": { "k2": { "k3": { "k4": "v" } } } }
和字段列表[“k1”,“k2”,“k3”],我需要检索部分{“k4”:“v”}.
下面是我的java7风格的代码:
// Ignore the map building code. Map map1 = new HashMap(); Map map2 = new HashMap(); Map map3 = new HashMap(); Map map4 = new HashMap(); map4.put("k4", "v"); map3.put("k3", map4); map2.put("k2", map3); map1.put("k1", map2); Map map = map1; System.out.println(map); //=> {k1={k2={k3={k4=v}}}} // Code to be transformed to java8 style List<String> fields = Arrays.asList("k1", "k2", "k3"); for(String field: fields) { map = (Map) map.get(field); } System.out.println(map); //=> {k4=v}
那么如何将上面的代码转换为java 8流式呢?
我不认为将其转化为功能性风格有任何好处;循环很好,精确地表达你正在做的事情.但为了完整起见,您可以通过以下方式执行此操作:
map = (Map)fields.stream() .<Function>map(key -> m -> ((Map)m).get(key)) .reduce(Function.identity(), Function::andThen).apply(map);
这会将每个键转换为能够对该键进行地图查找的函数,然后将它们组合成应用于您的映射的单个函数.将操作推迟到该点是必要的,因为不允许函数修改局部变量.
也可以将map操作与reduce操作融合,这允许省略显式类型(< Function>):
map = (Map)fields.parallelStream() .reduce(Function.identity(), (f, key)->f.andThen(m->((Map)m).get(key)), Function::andThen) .apply(map);
也许你现在认识到,这是一个简单的for循环更适合的任务.