如何从Java8orelse/orElseGet操作符返回HashMap

如何从Java8orelse/orElseGet操作符返回HashMap,java,java-8,java-stream,Java,Java 8,Java Stream,我试图从orElse/OrelGet流操作符返回HashMap,但它似乎无法在这些操作符中使用HashMap public class Main { public static void main(String args[]) { List<String> names = new ArrayList<String>() {{ add("test1"); }}; HashMap<Int

我试图从orElse/OrelGet流操作符返回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");
                }});
    }
}
公共类主{
公共静态void main(字符串参数[]){
列表名称=新的ArrayList(){{
添加(“测试1”);
}};
HashMap indexToNameMap=names.stream()
.filter(name->name.equals(“测试”))
.map(名称->新建HashMap(){{
put(名称。indexOf(名称),名称);
}})
.findFirst()
.orElseGet(()->new HashMap(){{
put(0,“不可用”);
}});
}
}
错误:

Bad return type in lambda expression: HashMap<Integer, String> cannot be converted to HashMap<Integer, String>
lambda表达式中的返回类型错误:无法将HashMap转换为HashMap 如何解决这个问题

这是:

        .map(name -> new HashMap<Integer, String>() {{
            put(index.incrementAndGet(), name);
        }})
但这是相当冗长的;不管怎样,双大括号初始化都很糟糕。使用集合。单音映射:

        .map(name -> Collections.singletonMap(index.incrementAndGet(), name))
或者在不使用匿名类的情况下编写它,作为lambda语句:

        .map(name -> {
            HashMap<Integer, String> map = new HashMap<>();
            map.put(index.incrementAndGet(), name);
            return map;
        })
.map(名称->{
HashMap=newHashMap();
map.put(index.incrementAndGet(),name);
返回图;
})
此处:

.orElseGet(() -> new HashMap<Integer, String>() {{put(0, "UN_AVAILABLE");}})
.orElseGet(()->newhashmap(){{put(0,“UN_可用”);})
这里的语法元素混合得很糟糕。你可能在想:

new HashMap<>() { 
  { put(0, "whatever"); }
}
newhashmap(){
{put(0,“任意”);}
}
换句话说:HashMap的匿名内部类,它有一个添加成员的初始值设定项块。简单地说:不要这样做(不是在这里,不是在任何代码中)。虽然这样做有效,但大多数人认为这是一种不好的做法

相反,直接将物品放入lambda体内:

() -> {
  HashMap<Integer, String> rv = new HashMap<>();
  rv.put(....)
  return rv;
}  
()->{
HashMap rv=新的HashMap();
rv.put(…)
返回rv;
}  

为了让事情更清楚,只需声明一个
双功能
,该功能创建映射并使用指定的条目对其进行初始化:

final BiFunction<Integer, String, HashMap<Integer, String>>  newHashMap = 
(k, v) ->{
   HashMap<Integer, String> map = new HashMap<>(); 
   map.put(k, v);
   return map;
}

HashMap<Integer, String> indexToNameMap = names.stream()
            .filter(name -> name.equals("test"))
            .map(name -> newHashMap.apply(index.incrementAndGet(), name))
            .findFirst()
            .orElseGet(() -> newHashMap.apply(0,  "UN_AVAILABLE"))
final双函数newHashMap=
(k,v)->{
HashMap=newHashMap();
map.put(k,v);
返回图;
}
HashMap indexToNameMap=names.stream()
.filter(name->name.equals(“测试”))
.map(name->newHashMap.apply(index.incrementAndGet(),name))
.findFirst()
.orElseGet(()->newHashMap.apply(0,“UN_可用”))

并非真正与问题相关,而是编辑:实际上它与此处的问题相关。除了问题之外,是否存在为每个过滤条目创建
HashMap
s并使用相同的
名称
然后从中找到第一个条目的实际用例?您确定不想以某种方式执行
contains
?此外,您还可以研究
收集器的
计数
实现,如果实际用例是这样的话,您可以利用它。另外:在这里使用
AtomicInteger.incrementAndGet()
似乎是不明智的。您希望具有连续键的
映射
实际上是一个
列表
。为什么不只是
集合。singletonMap(索引、名称)
?在较新版本中,
Map.of(index,name)
?@seenimurugan,OP,似乎您只需要
names.indexOf(“test”)
。编写这么复杂的代码有什么意义?谢谢@AndyTurner。你是一个明星。我现在正在使用Map.of(name::indexOf,name)当然。你可能在想:“我不同意:这可能不是OP的想法,即使它是有效地写的。我认为OP想到的是“这是一种创建和填充HashMap的简洁方法”,而没有意识到语法错误的阴暗面,即双括号初始化:)是的,你是对的@AndyTurner。我没有意识到双大括号初始化的黑暗面。这真的让它变得更清晰了吗<代码>集合。singletonMap
在没有双函数声明的情况下可以实现大致相同的效果。@Andy Turner比这两个初始值设定项更清楚。比较可比较的事物。还要注意,
singletonMap()
返回一个不可变的映射。这不是这个问题的要求。然后使用
newhashmap(singletonMap(…)
@Andy Turner。此外,您将创建两次(对于每个HashMap),否则您将使用非对称HashMap实例化。你觉得越接近它越清晰?我不知道。然后把它写成“真实”的方法。使用显式函数类型声明和初始化变量应该很少进行。
final BiFunction<Integer, String, HashMap<Integer, String>>  newHashMap = 
(k, v) ->{
   HashMap<Integer, String> map = new HashMap<>(); 
   map.put(k, v);
   return map;
}

HashMap<Integer, String> indexToNameMap = names.stream()
            .filter(name -> name.equals("test"))
            .map(name -> newHashMap.apply(index.incrementAndGet(), name))
            .findFirst()
            .orElseGet(() -> newHashMap.apply(0,  "UN_AVAILABLE"))