выбор объектов по атрибуту или типу из группы объектов - PullRequest
0 голосов
/ 13 ноября 2011

Представьте, что у меня есть группа сложных объектов, скажем, у них есть имя, фамилия и цвет.

Я хочу получить выборку всех объектов в этой группе, которые красного цвета и имеют фамилию, которая начинается с "K".

включает ли java структуру данных, в которой я могу хранить эти объекты, что позволяет делать такой выбор? Есть ли элегантное решение для этого, которое не требует написания множества циклов for?

Я бы хотел сделать это без использования библиотек базы данных Java.

Ответы [ 3 ]

0 голосов
/ 13 ноября 2011

Проект http://www.glazedlists.com/ имеет GroupingList, который позволяет группировать элементы списка по вашему собственному компаратору. Вот ссылка на GroupingList: http://publicobject.com/glazedlists/glazedlists-1.8.0/api/ca/odell/glazedlists/GroupingList.html

0 голосов
/ 13 ноября 2011

Вот пример чуть выше моей головы (я не реализовывал методы удаления):

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;
        }
    }
}
0 голосов
/ 13 ноября 2011

AFAIK, в Java нет структуры данных, которая позволяла бы вам выполнять эти операции «из коробки». Вам понадобится что-то вроде инвертированного индекса , чтобы это работало. Lucene позволяет вам выполнять все операции поиска, которые вы только что сказали, очень эффективно. Я считаю, что у него также есть хранилище In-Memory, поэтому его должно быть достаточно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...