简体   繁体   English

集合函数方法调用get,put等吗?

[英]Do Collections functional methods call get, put, etc?

I've spent many years working with Java 1.6 (maintaining legacy tools) and am just starting to migrate to 1.8. 我花了很多年时间使用Java 1.6(维护传统工具)并且刚刚开始迁移到1.8。 One big change is the functional methods in the java.util.Collections suite. 一个重大变化是java.util.Collections套件中的功能方法。 The biggest concern for me is I have several collection extensions which apply careful checks or algorithms on modification. 对我来说最大的担忧是我有几个集合扩展,它们需要仔细检查或修改算法。 Do the default methods call the already defined put(..), get(...), remove(..) etc functions or do I have to do a major rework to make this work? 默认方法是调用已经定义的put(..),get(...),remove(..)等函数还是我必须做一个重大的返工来使这个工作?

Eg (ignoring null checks, etc. map that only holds values <= 10) 例如(忽略空检查等等只包含值<= 10的地图)

public class LimitedMap extends HashMap<String, Integer>{
    @Override
    public Integer put(String key, Integer value){
        if(value> 10) throw new IllegalArgumentException();
        return super.put(key, value);
    }

    @Override
    public Integer computeIfAbsent(String key, Function<? super String, ? extends Integer> mappingFunction) {
        return super.computeIfAbsent(key, mappingFunction);
    }
}

With this pair of functions: would I still have to do a detailed override and put new checks into the computeIfAbsent function? 使用这对函数:我是否还需要进行详细的覆盖并将新的检查放入computeIfAbsent函数中?

The only way you could be certain that only the interface methods from pre Java 8 can be used is if you somehow could delegate to the default method implementation in the interface ( Map<K, V> in this case). 唯一可以确定只能使用Java 8之前的接口方法的方法是,如果你能以某种方式委托接口中的默认方法实现(在本例中为Map<K, V> )。

That is, if you could write something like the following (which you can't). 也就是说,如果你可以写下面的东西(你不能)。

public class LimitedMap extends HashMap<String, Integer> {

    @Override
    public Integer computeIfAbsent(String key,
            Function<? super String, ? extends Integer> mappingFunction) {

        return Map.super.computeIfAbsent(key, mappingFunction);
    }
}

Unfortunately that is not legal since you only can invoke the method that you've overriden (here the one from HashMap<String, Integer> ) but not the one which the inherited method might have overridden (these are the normal rules for super method invocation). 不幸的是,这不合法,因为你只能调用你覆盖的方法(这里是来自HashMap<String, Integer> ),而不是继承方法可能被覆盖的方法(这些是super方法调用的常规规则) )。

So the only workaround I see for your situation is to create a copy of the interface default method implementation in a helper class like this: 因此,我看到的唯一解决方法是在辅助类中创建接口默认方法实现的副本,如下所示:

public class Maps {

    public static <K, V> V computeIfAbsent(Map<K, V> map,
            K key, Function<? super K, ? extends V> mappingFunction) {
        Objects.requireNonNull(mappingFunction);
        V v;
        if ((v = map.get(key)) == null) {
            V newValue;
            if ((newValue = mappingFunction.apply(key)) != null) {
                map.put(key, newValue);
                return newValue;
            }
        }

        return v;
    }
}

This is the implementation from java.util.Map as a static method enhanced by an additional parameter map for the instance to operate on. 这是java.util.Map的实现,作为静态方法,通过操作实例的附加参数map进行增强。

With such a helper class you could now write 有了这样的助手类,你现在可以写了

public class LimitedMap extends HashMap<String, Integer> {

    @Override
    public Integer computeIfAbsent(String key,
            Function<? super String, ? extends Integer> mappingFunction) {

        return Maps.computeIfAbsent(this, key, mappingFunction);
    }
}

That's not the prettiest solution but one that should work with a limited amount of effort. 这不是最漂亮的解决方案,但应该只需要付出有限的努力。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么集合中的方法没有放在AbstractCollection中? - Why methods from Collections were not put in AbstractCollection? 放置集合中的Java并发 - Java Concurrency in put/get in collections 如何在没有 .Method() 的情况下调用函数式接口中的方法 - How to call methods in functional interfaces without .Method() 为什么我需要使用Paths.get()来获取Path? 为什么没有.delete()等方法呢? - Why do I need to use Paths.get() to get a Path? Why aren't there .delete(), etc methods on it? 方法是否只进行同步,以便我们可以在以下代码中调用notifyAll() - Are the methods get and put only synchronized so that we can call notifyAll() in the following code 可以安全地在Collections.synchronizedX的结果上调用Java 8 Collection默认方法吗? - Safe to call Java 8 Collection default methods on results of Collections.synchronizedX? 在何处(哪一层)放置实体查询方法,“持久”方法等? - Where (which layer) to put Entity query methods, “persist” methods etc.? 我在哪里将我的方法放在MVC上? - Where do I put my methods with MVC? Java TreeMap实现的get和put方法 - Java TreeMap implementation get and put methods 在GET / POST / PUT调用之后,如何从RestTemplate获得转换后的请求? - How do you get a converted request from RestTemplate after a GET/POST/PUT call?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM