注意:代码是线程安全的,换句话说,是单线程的。只有我可以从听众列表中删除自己。
我有1000个不同的侦听器ArrayLists,我必须通过以下代码通知:
protected void onFlushed() {
int size = listeners.size();
for (int i = 0; i < size; i++) {
listeners.get(i).onFlushed();
int newSize = listeners.size();
if (newSize == size - 1) {
size--;
i--;
} else if (newSize != size) {
throw new ConcurrentModificationException("List was altered while iterating! oldSize=" + size + " newSize=" + newSize);
}
}
}
是否有一种智能方法可以创建一个Notifier类,它可以接受任何侦听器的ArrayList以及任何侦听器方法,并为我执行下面的逻辑,或者我必须为每个侦听器方法复制上面的代码?
我从Java那里问过多吗? :(
答案 0 :(得分:3)
首先,我有点担心这样的事实,即大多数代码似乎都是以非常安全的方式处理并发问题。考虑对访问同一个侦听器列表的任何代码进行一些锁定。这样,您可以将此代码简化为:
protected void onFlushed() {
synchronized(listeners) {
for (FlushListener listener : listeners) {
listener.onFlushed();
}
}
}
重复你的代码并不是太糟糕。话虽如此,如果有某些原因你需要你拥有的逻辑,你可以创建一个这样的类:
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
public class Notifier<T> {
public static interface NotificationRunnable<T> {
public void notify(T t);
}
private ArrayList<T> listeners;
public Notifier() {
listeners = new ArrayList<T>();
}
public void addListener(T t) {
listeners.add(t);
}
public void notifyAll(NotificationRunnable<T> nr) {
int size = listeners.size();
for (int i = 0; i < size; i++) {
nr.notify(listeners.get(i));
int newSize = listeners.size();
if (newSize == size - 1) {
size--;
i--;
} else if (newSize != size) {
throw new ConcurrentModificationException("List was altered while iterating! oldSize=" + size + " newSize=" + newSize);
}
}
}
}
然后调用它的代码看起来像:
Notifier<FlushListener> notifier = new Notifier();
notifier.addListener(new FlushListener());
public void onFlushed() {
notifier.notifyAll(new NotificationRunnable<FlushListener>(){
public void notify(FlushListener t) {
t.onFlushed();
}
});
}
甚至可以在实际方法中将其缩小到一行:
NotificationRunnable<FlushListener> flushRunnable = new NotificationRunnable<FlushListener>(){
public void notify(FlushListener t) {
t.onFlushed();
}
}
public void onFlushed() {
notifier.notifyAll(flushRunnable);
}
答案 1 :(得分:2)
在当前的Java中,没有办法像函数式语言那样传递方法,但是你可以创建一个Function<Domain, Range>
接口并传递实现该接口的对象。
您可以考虑使用Guava,它提供类似功能习语和列表理解的内容。