Java 统计所有调用以在Hashmap中添加键值

Java 统计所有调用以在Hashmap中添加键值,java,Java,在浏览HashMap实现和一些教程时,我想到了这个问题。但不知道如何解决这个问题。如果你们能帮我的话,就在这里发帖。我想对所有调用进行计数,以便在映射中添加每个键值对。它还应该计算对put、putAll和putIfAbsent所有方法的调用。主要有两个选项 使用继承 假设要跟踪的Map实现允许扩展,然后创建一个子类并重写所需的方法 在重写的方法中,执行自定义逻辑(count),然后调用基类的super.方法(实际方法) 这种方法的主要优点是,instanceof和generics编译器行为将是有

在浏览HashMap实现和一些教程时,我想到了这个问题。但不知道如何解决这个问题。如果你们能帮我的话,就在这里发帖。我想对所有调用进行计数,以便在映射中添加每个键值对。它还应该计算对put、putAll和putIfAbsent所有方法的调用。

主要有两个选项

使用继承
  • 假设要跟踪的
    Map
    实现允许扩展,然后创建一个子类并重写所需的方法
  • 在重写的方法中,执行自定义逻辑(count),然后调用基类的
    super.
    方法(实际方法)
  • 这种方法的主要优点是,
    instanceof
    generics
    编译器行为将是有利的

    这种方法有一个主要问题,即您需要扩展每个需要支持的
    Map
    类。这将导致班级爆炸

    使用构图
  • 添加实现映射的新类(每个顶级相关类型)
  • 有一个实际地图的参考变量
  • 从Map接口实现这些方法
  • 在实现中,执行跟踪操作并调用引用变量所指向的映射
  • 这种方法的主要优点是,新类很少

    这种行为的缺点是
    instanceof
    generic
    类型可能无法按用户预期工作

    建议
  • 如果您计划在某些大型应用程序中使用此功能,那么请进一步讨论未来可能的用例,并将地图创建部分抽象为某些工厂方法甚至工厂。 这将允许您在工厂中封装实现细节
  • 或者尝试使用方法拦截器。虽然这可能会略微增加延迟,但这不需要客户机做太多更改,也可以避免维护
    Map
    实现的并行层次结构
  • 如果使用拦截器,我不知道你能控制的详细程度。同样,这也将是复杂的
  • 学习这些技巧是很好的。请不要在生产代码中使用它们,直到它成为唯一可能的选项
  • 笔记
  • 精确定义
    count
    的含义
  • 是否只统计来自此类用户的呼叫
  • 或者,甚至这个类中出现的调用也可以计数(比如
    add
    calling
    get
    来查找存在)

  • 主要有两种选择

    使用继承
  • 假设要跟踪的
    Map
    实现允许扩展,然后创建一个子类并重写所需的方法
  • 在重写的方法中,执行自定义逻辑(count),然后调用基类的
    super.
    方法(实际方法)
  • 这种方法的主要优点是,
    instanceof
    generics
    编译器行为将是有利的

    这种方法有一个主要问题,即您需要扩展每个需要支持的
    Map
    类。这将导致班级爆炸

    使用构图
  • 添加实现映射的新类(每个顶级相关类型)
  • 有一个实际地图的参考变量
  • 从Map接口实现这些方法
  • 在实现中,执行跟踪操作并调用引用变量所指向的映射
  • 这种方法的主要优点是,新类很少

    这种行为的缺点是
    instanceof
    generic
    类型可能无法按用户预期工作

    建议
  • 如果您计划在某些大型应用程序中使用此功能,那么请进一步讨论未来可能的用例,并将地图创建部分抽象为某些工厂方法甚至工厂。 这将允许您在工厂中封装实现细节
  • 或者尝试使用方法拦截器。虽然这可能会略微增加延迟,但这不需要客户机做太多更改,也可以避免维护
    Map
    实现的并行层次结构
  • 如果使用拦截器,我不知道你能控制的详细程度。同样,这也将是复杂的
  • 学习这些技巧是很好的。请不要在生产代码中使用它们,直到它成为唯一可能的选项
  • 笔记
  • 精确定义
    count
    的含义
  • 是否只统计来自此类用户的呼叫
  • 或者,甚至这个类中出现的调用也可以计数(比如
    add
    calling
    get
    来查找存在)

  • 您可以创建一个包装器来实现映射接口,并将映射作为构造函数参数记录调用的位置。然后将所有调用委托给该映射,并另外进行日志记录:

    public class LoggingMap<K,V> implements Map<K,V> {
        private Map<K,V> wrapped;
    
        public LoggingMap<K,V> (Map <K,V> wrapping) {
            wrapped = wrapping;
        }
    
        @Override
        public xy(...) {
            System.out.println("calling xy"); // log the call
            wrapped.xy(...);                  // delegate to the original map
        }
        
        // repeat for *all* methods of the map interface
    }
    
    公共类LoggingMap实现映射{
    私人地图包装;
    公共日志地图(地图换行){
    包裹=包裹;
    }
    @凌驾
    公共xy(…){
    System.out.println(“调用xy”);//记录调用
    wrapped.xy(…);//委托给原始映射
    }
    //对map界面的*all*方法重复此操作
    }
    
    您可以创建一个包装器,该包装器实现映射接口,并将映射作为构造函数参数记录调用。然后将所有调用委托给该映射,并另外进行日志记录:

    public class LoggingMap<K,V> implements Map<K,V> {
        private Map<K,V> wrapped;
    
        public LoggingMap<K,V> (Map <K,V> wrapping) {
            wrapped = wrapping;
        }
    
        @Override
        public xy(...) {
            System.out.println("calling xy"); // log the call
            wrapped.xy(...);                  // delegate to the original map
        }
        
        // repeat for *all* methods of the map interface
    }
    
    公共类LoggingMap实现映射{
    私人地图包装;
    公共日志地图(地图换行){
    包裹=包裹;
    }
    @凌驾
    公共xy(…){
    System.out.println(“调用xy”);//记录调用
    wrapped.xy(…);//委托给原始映射
    }
    //对map界面的*all*方法重复此操作
    }
    
    <dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.2.10</version>
    </dependency>
    
    get: 5
    put: 4