如何从Java 8 orElse / orElseGet运算符返回HashMap

see*_*gan -2 java java-8 java-stream

我正在尝试从orElse / orElseGet流运算符返回HashMap,但似乎无法在这些运算符中使用HashMap。

public class Main {
    public static void main(String args[]) {

        List<String> names = new ArrayList<String>() {{
            add("test1");
        }};

        HashMap<Integer, String> indexToNameMap = names.stream()
                .filter(name -> name.equals("test"))
                .map(name -> new HashMap<Integer, String>() {{
                    put(names.indexOf(name), name);
                }})
                .findFirst()
                .orElseGet(() -> new HashMap<Integer, String>() {{
                    put(0, "UN_AVAILABLE");
                }});
    }
}
Run Code Online (Sandbox Code Playgroud)

错误:

Bad return type in lambda expression: HashMap<Integer, String> cannot be converted to HashMap<Integer, String>
Run Code Online (Sandbox Code Playgroud)

如何解决这个问题?

And*_*ner 6

这个:

        .map(name -> new HashMap<Integer, String>() {{
            put(index.incrementAndGet(), name);
        }})
Run Code Online (Sandbox Code Playgroud)

正在创建-的匿名子类,HashMap这是此阶段之后流的实际类型。这Stream<YourClass$1>之后有点像。

因此,您orElseGet必须返回相同类型的东西(或子类),但是不能返回,因为映射返回了匿名类型,并且无法在代码的其他地方访问。

最小的更改将是:

    .map(name -> (HashMap<Integer, String>) new HashMap<Integer, String>() {{
        put(index.incrementAndGet(), name);
    }})
Run Code Online (Sandbox Code Playgroud)

但这很冗长;而且无论如何都需要进行双括号初始化。可以使用Collections.singletonMap

        .map(name -> Collections.singletonMap(index.incrementAndGet(), name))
Run Code Online (Sandbox Code Playgroud)

或仅在没有匿名类的情况下将其编写为lambda语句:

        .map(name -> {
            HashMap<Integer, String> map = new HashMap<>();
            map.put(index.incrementAndGet(), name);
            return map;
        })
Run Code Online (Sandbox Code Playgroud)