首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Java中侦听HashMap的特定键值的变化

如何在Java中侦听HashMap的特定键值的变化
EN

Stack Overflow用户
提问于 2022-04-13 08:40:50
回答 1查看 254关注 0票数 2

我必须等到HashMap键的值从另一个线程改变,然后再继续请求处理。

EN

回答 1

Stack Overflow用户

发布于 2022-04-13 13:54:52

我认为最灵活的解决方案将是实现观测器模式

自JDK版本9以来,Note就不再推荐使用ObserverObservable,即使您使用的是Java 8,也不要使用它们。它们的问题是,它们的名称以及Observer的方法名称Observer没有向代码的读者说明触发的事件以及随后可能发生的操作。

从图中可以看到,subject应该包含观察者(或侦听器)的集合。

在您的示例中,主题应该是类,其中包含您想要侦听的HashMap更新。不要扩展映射,而是用类包装它。因为如果您选择扩展HashMap,您的代码将依赖于它的实现。而且,HashMap中的任何更改,例如,添加了新方法或改进了新方法,都可能破坏代码(这个主题在乔舒亚·布洛赫的“有效Java”一书中讨论过,有关更多信息,请看一看)。

假设我们有一个类OrderManager,它维护一个Order的映射,这个类将是一个subject

一些服务,如LoggingManagerand maybe some more needs to notified new order was added. These are our ***observers***. All these classes an interface, let's sayOrderAddedListenerthat defines a single methodonOrderAdded(Order,BillingManager )‘,这是我们感兴趣的事件。

Note__,如果您需要侦听其他事件,如删除或更新,则需要定义一个新接口,该方法负责处理每个目标事件,正如接口隔离原则所示。

OrderManager必须有一组观察者。添加新订单时,subject将遍历观察者的集合,并对每个观察者调用onOrderAdded()方法。

为了添加一个需要侦听添加顺序事件的观察者,OrderManager必须定义一个方法来注册它,同时也是一个很好的做法,添加另一个方法来注销已经注册的观察者,以便在您不再需要它时删除它。

异步处理

Note,在本例中,事件是在同一个线程中处理的。如果观察者执行的操作是昂贵的,或者可能阻塞线程,为了异步地触发它们,您可以创建一个类,该类将实现Runnable并保存对观察者和事件的引用(命令添加/更新),方法run()将触发观察者。当发生新事件时,OrderManager不应该在每个观察者上调用onOrderAdded(),而是应该创建该类的一个新实例,通过向其构造函数传递一个观察者和一个新的顺序来实现runnable,然后创建和触发一个新线程。

这是一种简化的方法。但我想这会给你一个大致的理解。

实施实例

这可能是什么样子:

代码语言:javascript
运行
复制
public class OrderManager {
    private Map<Long, Order> orderById = new HashMap<>();
    private Set<OrderAddedListener> listeners = new HashSet<>();
    
    public void addOrder(Order order) {
        // notifying observers
        listeners.forEach(observer -> observer.onOrderAdded(order));
        
        orderById.put(order.getId(), order);
    }
    
    // more methods like removeOrder(), getOrderCount() etc.
    
    public boolean registerOrderAddedListener(OrderAddedListener listener) {
        return listeners.add(listener);
    }
    
    public boolean unregisterOrderAddedListener(OrderAddedListener listener) {
        return listeners.remove(listener);
    }
}

public interface OrderAddedListener {
    void onOrderAdded(Order order);
}

public class LoggingManager implements OrderAddedListener {
    private Logger logger;
    
    @Override
    public void onOrderAdded(Order order) {
//        logger.log();
        System.out.println("Log message has been written");
    }
}

public class BillingManager implements OrderAddedListener {
    private BillingService billingService;
    
    @Override
    public void onOrderAdded(Order order) {
//        billingService.sendBill(order);
        System.out.println("A bill has been sent");
    }
}

main() -一个简单的演示

代码语言:javascript
运行
复制
public static void main(String[] args) {
    OrderManager orderManager = new OrderManager();
    orderManager.registerOrderAddedListener(new LoggingManager());
    orderManager.registerOrderAddedListener(new BillingManager());
    orderManager.addOrder(new Order());
}

输出

代码语言:javascript
运行
复制
A log message has been written
A bill has been sent
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71854454

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档