Java - получение количества типов в списке - PullRequest
3 голосов
/ 07 декабря 2009

У меня есть список. Список может содержать несколько элементов одного и того же типа перечисления.

Допустим, у меня есть перечисление: TOY, которое имеет значения: BALL, DOLL, PLAYSTATION. Я хочу знать, сколько PLAYSTATION элементов в списке с типом TOY. (т.е. List<Toy> игрушки)

Какое наилучшее решение для этого? Я не хочу повторять список каждый раз.

Ответы [ 8 ]

8 голосов
/ 07 декабря 2009

Вы можете использовать Apache commons-collection 'HashBag. У него есть метод getCount(Object), который подойдет вам.

2 голосов
/ 07 декабря 2009

java.util.Collections имеет метод с именем frequency(Collection c, Object type).

Использование в моем вопросе:

int amountOfPlayStations = Collections.frequency(toys, TOY.PLAYSTATION);
1 голос
/ 07 декабря 2009

Если вы не хотите каждый раз перебирать всю коллекцию, другой альтернативой будет написать реализацию ForwardingList . Основные преимущества по сравнению с предложением HashBag:

  • поддерживает дженерики
  • он реализует интерфейс List, поэтому вы можете передать его любому методу, который ожидает List

Однако у этого подхода есть и обратная сторона: для его запуска вам нужно написать немного кода для подключения.

Ниже приведен краткий пример того, как вы могли это сделать. Обратите внимание, что если вы сделаете это, вы должны переопределить все методы, которые добавляют / удаляют из списка, иначе вы можете оказаться в несогласованном состоянии:

import com.google.common.collect.ForwardingList;


public class CountingList<E> extends ForwardingList<E> {

    private List<E> backingList = new LinkedList<E>();
    private Map<E, Integer> countMap = new HashMap<E, Integer>();

    @Override
    protected List<E> delegate() {
        return backingList;
    }

    @Override
    public boolean add(E element) {
        backingList.add(element);
        if(countMap.containsKey(element)) {
            countMap.put(element, countMap.get(element) + 1);
        } else {
            countMap.put(element, 1);
        }
        return true;
    }

    public int getCount(E element) {
        Integer count = countMap.get(element);
        return count != null ? count.intValue() : 0;
    }

}
1 голос
/ 07 декабря 2009

По крайней мере, такой служебный метод, как:

public int count(List<Toy> haystack, Toy needle) {
    int result;
    for (Toy t : haystack) {
        if (t == needle) {
           result++;
        }
    }
    return result;
}

Позволит вам кратко сослаться на количество PLAYSTATION из других частей кода. В качестве альтернативы, если вы знали, что список вряд ли изменится, построение Map<Toy, Integer> позволит вам увеличить количество всех элементов за один раз.

1 голос
/ 07 декабря 2009

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

Все, что вам нужно сделать, это переопределить методы add / remove / addAll и т. Д. И увеличить счетчики перед передачей их в реальный тип списка. Самое приятное в этом то, что вы можете украсить любой тип списка новой оболочкой.

0 голосов
/ 07 декабря 2009

Помимо всех этих решений (у меня есть слабость к вызову Collections.Frequency), я бы порекомендовал вам взглянуть на google collection , и особенно на [Collections2.transform] [2], который может дать вам живой вид на предметы.

[2]: http://google -collections.googlecode.com / svn / trunk / javadoc / com / google / common / collect / Collections2.html # transform (java.util.Collection , com .google.common.base.Function)

0 голосов
/ 07 декабря 2009

Лучше всего подойдет HashBag (от Bozho). Но чуть более общим было бы Googles Collections 2 с соответствующим предикатом:

List<Toy> toys;
List<Toy> playstations = Collections2.filter( toys, new Predicate() {
  boolean apply(TOY toy){
    return toy == TOY.PLAYSTATION;
  }
});
0 голосов
/ 07 декабря 2009

Расширьте метод java.util.List и переопределите все методы мутатора, то есть те, которые используются для добавления или удаления элементов, а также те, которые используются для очистки списка. Добавьте ссылку на частный java.util.Map, который будет содержать количество элементов для каждого типа. Добавьте методы доступа, которые будут возвращать текущее количество элементов для каждого типа.

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