5

假设我有一个List<Person> all数据结构,其中Person定义为:

class Person {
   String firstName;
   String secondName;
   boolean hasValidDrivingLicense;
}

我想保留一个List<Person> drivers仅包含拥有有效驾驶执照的人的冗余。我认为它也可以被视为一个索引(一个索引将包含所有项目,但目的非常相似)。
这是为了避免每次我需要这些数据时都需要遍历整个列表。
(每次循环的优点是我对我的 hasValidDrivingLicense 信息有一个单一的权威表示;放弃这条路需要:a)有效的原因 b)经过测试的替代方案。原因取决于具体问题;另一种方法是我在这里开发的:-)) 我可能有这样
的问题:

void add(Person p) {
   all.add(p);
   if (p.hasValidDrivingLicense()) {
       drivers.add(p);
   }
}

这通常有效。

Person p = new Person(); //then set fields, of course.
add(p);
p.setHasValidDrivingLicense(true);

这里没有。 所以问题是:冗余信息可能会错位。索引可能会“损坏”。

解决方案

  1. Person 的 hasValidDrivingLicense 属性实现 Observable 设计模式(或发布-订阅者,摇摆中的内容基于 Listener 接口) index-mantainer 对象已更改相关属性。Observable 似乎是一个明确的解决方案。没有任何问题。
  2. 人是不可变的

问题

不变性似乎是一个可行的解决方案,但是,从集合维护者的角度来看,这是编写代码的人:

public void add(Person p) {
     ...
}

必须确保 p 是不可变的或更好的,至少 hasValidDrivingLicense 是最终的。

a)这可以通过反射来完成(http://stackoverflow.com/questions/203475/how-do-i-identify-immutable-objects-in-java)但这不需要新的性能评估吗?反思不是有代价的吗?

b)可能在设计模式或语言的新特性(例如注释)中是否有解决这个问题的其他解决方案?

4

1 回答 1

2

我猜你想要的是你所有收藏的“实时”过滤视图。

这可以通过 Google Guava 和 Predicate 很好地完成:

http://docs.guava-libraries.googlecode.com/git-history/v11.0.2/javadoc/com/google/common/collect/Collections2.html#filter%28java.util.Collection,%20com.google.common .base.Predicate%29

另一方面,仅实现 List peopleWithDriversLicens() {...} 也很容易,因此 Guava 可能是矫枉过正 - 取决于您的需求,包括性能特征。

于 2012-04-10T10:12:17.933 回答