Java8,Lambda:用Lambda替换匿名内部类

Java8,Lambda:用Lambda替换匿名内部类,java,lambda,java-8,Java,Lambda,Java 8,我有一个包含以下内容的类: List roles = ldapTemplate.search(baseDn, replaceFilter, sc, new AttributesMapper() { public Object mapFromAttributes(Attributes attrs) throws NamingException { retu

我有一个包含以下内容的类:

List roles = ldapTemplate.search(baseDn, replaceFilter, sc,
            new AttributesMapper() {
                public Object mapFromAttributes(Attributes attrs)
                        throws NamingException {
                    return attrs.get("cn").get();
                }
            });
IntelliJ告诉我用lambda替换匿名内部类。 所以我试着:

List roles = ldapTemplate.search(
    baseDn, replaceFilter, sc,
    (Attributes a)  -> { return a.get("cn").get(); };
);
但是,我得到一个编译错误:

Error:(46, 50) java: incompatible types: inference variable T has incompatible bounds
    equality constraints: java.lang.String
    lower bounds: java.lang.Object
我找不到这个问题的解决办法。你有什么想法吗?

试试这个(去掉多余的分号)


我有一种强烈的感觉,你没有在你的问题中发布准确的代码。比如,我不能用你发布的代码重现错误

然而,让我印象深刻的是你对原始类型的使用。如果原始代码如下所示:

List<String> roles = ldapTemplate.search(baseDn, replaceFilter, sc,
    new AttributesMapper() {
        public Object mapFromAttributes(Attributes attrs)
                throws NamingException {
            return attrs.get("cn").get();
        }
    });
现在,编译器将为您推断类型
AttributesMapper
,并产生错误,因为lambda表达式返回的是
Object
,而不是
String
,因此无法实现
AttributesMapper
接口

您可以通过插入类型转换来实现
AttributesMapper
接口,或者通过使用原始类型
列表
声明
roles
来解决此问题。但是,使用类型转换将是更干净的方法(并且应该是唯一不会产生编译器警告的方法):

List roles=ldapTemplate.search(baseDn、replaceFilter、sc、,
a->(字符串)a.get(“cn”).get();

(我简化了表达式以补偿包含的类型转换,看起来好多了,不是吗?

一个简单的azure存储实体解析器接口及其实现方法:

EntityResolver<String> orderNumberResolver = new EntityResolver<String>() {
    @Override
    public String resolve(String partitionKey, String rowKey, Date timeStamp,
        HashMap<String, EntityProperty> properties, String etag) {
      return properties.get("SomeColumnName").getValueAsString();
    }
  };
EntityResolver orderNumberResolver=new EntityResolver(){
@凌驾
公共字符串解析(字符串分区键、字符串行键、日期时间戳、,
HashMap属性,字符串etag){
返回properties.get(“SomeColumnName”).getValueAsString();
}
};
上述方法的λ为:

 EntityResolver<String> orderNumberResolver = (
          partitionKey, rowKey, timeStamp, properties, etag
      ) -> properties.get("SomeColumnName").getValueAsString();
EntityResolver orderNumberResolver=(
partitionKey、rowKey、时间戳、属性、etag
)->properties.get(“SomeColumnName”).getValueAsString();

从上面的例子可以清楚地看出,lambda足够聪明,可以根据其匿名内部类处理方法参数的类型,因此它使得重写方法的实现变得容易。希望这会有所帮助。

下面的代码显示了使用匿名内部类获取学生比较器

private static final Comparator<StudentDto> studentScoreComparator = new Comparator<StudentDto>() {
            @Override
            public int compare(StudentDto s1, StudentDto s2) {
              if (s2.getScore() < s1.getScore()) {
                return 1;
              }
              return s2.getScore() == s1.getScore() ? 0 : 1;
            }
          };
private static final Comparator studentScoreComparator=new Comparator(){
@凌驾
公共整数比较(学生数据到s1,学生数据到s2){
if(s2.getScore()
使用java8amdsonar建议只包含一个方法的匿名内部类应该成为lambdas 可以按如下方式转换

private static final Comparator<StudentDto> studentScoreComparator = (s1, s2) -> {
        if (s2.getScore() < s1.getScore()) {
          return 1;
        }
        return s2.getScore() == s1.getScore() ? 0 : 1;
      };
private static final Comparator studentScoreComparator=(s1,s2)->{
if(s2.getScore()
只有一个方法实现的匿名内部类可以 作为功能接口考虑,可以很容易地被视为lambda 表情


看起来lambda的返回值需要转换为
字符串。
。是(属性a)->(字符串)a.get(“cn”).get()一切正常。但我不明白为什么在我的内部类中,我返回一个对象,所有的东西都是好的,而不是lambda中的。我不确定,但它一定与类型推断有关。我刚刚在我的机器上做了一个简单的测试,它似乎不需要浇铸就可以工作。使用的Java版本是
Java版本“1.8.0_05”Java(TM)SE运行时环境(build 1.8.0_05-b13)Java热点(TM)64位服务器VM(build 25.5-b02,混合模式)
?啊,额外的分号。您可以将此添加到您的答案中吗?'List roles=ldapTemplate.search(baseDn,replaceFilter,sc,(a)->a.get(“cn”).get();'即使这样也应该行得通
 EntityResolver<String> orderNumberResolver = (
          partitionKey, rowKey, timeStamp, properties, etag
      ) -> properties.get("SomeColumnName").getValueAsString();
private static final Comparator<StudentDto> studentScoreComparator = new Comparator<StudentDto>() {
            @Override
            public int compare(StudentDto s1, StudentDto s2) {
              if (s2.getScore() < s1.getScore()) {
                return 1;
              }
              return s2.getScore() == s1.getScore() ? 0 : 1;
            }
          };
private static final Comparator<StudentDto> studentScoreComparator = (s1, s2) -> {
        if (s2.getScore() < s1.getScore()) {
          return 1;
        }
        return s2.getScore() == s1.getScore() ? 0 : 1;
      };