【问题标题】:selecting objects by attribute or type from a group of objects从一组对象中按属性或类型选择对象
【发布时间】:2011-11-13 18:58:43
【问题描述】:

假设我有一组复杂的对象,假设它们有名字、姓氏和颜色。

我想检索该组中所有红色且姓氏以“K”开头的对象的选择。

java 是否包含一个数据结构,我可以在其中存储这些对象以允许这种选择?有没有不涉及编写一堆 for 循环的优雅解决方案?

我想在不使用任何 java 数据库的情况下执行此操作。

【问题讨论】:

  • 你可以自己实现。一些自定义集合,也将根据所需属性存储索引。添加对象时,它会扫描属性值并将对添加对象的引用存储在索引集合中。每个索引集合都可以实现为Map<Object, Set<Object>>,其中键是属性值,set - 是共享相同属性值的对象的集合。

标签: java search data-structures


【解决方案1】:

AFAIK,Java 中没有数据结构可以让您开箱即用地执行这些操作。你需要像inverted index 这样的东西来完成这项工作。 Lucene 让您可以非常高效地完成您刚才所说的所有搜索操作。我相信它也有一个 In-Memory 存储,所以应该足够了。

【讨论】:

    【解决方案2】:

    http://www.glazedlists.com/ 项目有一个 GroupingList,它可以让你在你自己的 Comparator 上对 List 的元素进行分组。这里是 GroupingList 的链接:http://publicobject.com/glazedlists/glazedlists-1.8.0/api/ca/odell/glazedlists/GroupingList.html

    【讨论】:

      【解决方案3】:

      这是我脑海中的一个示例(我没有实现删除方法):

      import java.lang.reflect.Field;
      import java.util.ArrayList;
      import java.util.HashMap;
      import java.util.HashSet;
      import java.util.List;
      import java.util.Map;
      import java.util.Map.Entry;
      import java.util.Set;
      
      public class IndexedCollection<E> extends ArrayList<E> {
          private Map<String, Map<Object, Set<E>>> indices = new HashMap<String,  Map<Object, Set<E>>>();
      
          public IndexedCollection(String...indices) {
              for (String index: indices) {
                  this.indices.put(index, new HashMap<Object, Set<E>>());
              }
          }
      
          public boolean add(E entry) {
              try {
                      Map<String, Object> objectIndices = collectIndices(entry);
      
                      for (Entry<String, Object> objectIndex: objectIndices.entrySet()) {
                          Map<Object, Set<E>> map = this.indices.get(objectIndex.getKey());
                          Set<E> set = map.get(objectIndex.getValue());
      
                          if (set == null) {
                              set = new HashSet<E>();
                              map.put(objectIndex.getValue(), set);
                          }
      
                          set.add(entry);
                      }
      
                      return super.add(entry);
              }
              catch (Exception e)
              {
                  throw new RuntimeException("Failed to collect object indices", e);
              }
          };
      
          public Set<E> findByIndex(String name, Object value) {
              Map<Object, Set<E>> index = this.indices.get(name);
      
              if (index != null)
                  return index.get(value);
      
              return null;
          }
      
          public Set<E> findByIndices(Index...indices) {
              Set<E> results = null;
      
              for (Index index: indices) {
                  Set<E> tmp = findByIndex(index.name, index.value);
      
                  if (tmp.size() == 0)
                      return null;
      
                  if (results == null)
                      results = tmp;
                  else {
                      Set<E> newResult = new HashSet<E>();
                      for (E value: results) {
                          if (tmp.contains(value))
                              newResult.add(value);
                      }
      
                      results = newResult;
      }
              }
      
              return results;
          }
      
          private Map<String, Object> collectIndices(E e) throws IllegalArgumentException, IllegalAccessException {
              Map<String, Object> indices = new HashMap<String, Object>();
      
              Field[] fields = e.getClass().getDeclaredFields();
      
              for (Field field: fields) {
                  if (this.indices.containsKey(field.getName())) {
                      boolean accessible = field.isAccessible();
                      field.setAccessible(true);
                      indices.put(field.getName(), field.get(e));
                      field.setAccessible(accessible);
                  }
              }
      
              return indices;
          }
      
          public static class Index {
              private String name;
              private Object value;
      
              public Index(String name, Object value) {
                  this.name = name;
                  this.value = value;
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2020-09-16
        • 1970-01-01
        • 1970-01-01
        • 2015-11-05
        • 1970-01-01
        • 2021-04-06
        • 2015-10-30
        • 1970-01-01
        • 2016-11-02
        相关资源
        最近更新 更多