Как посчитать количество вхождений элемента в список - PullRequest
155 голосов
/ 03 февраля 2009

У меня есть ArrayList, класс коллекции Java, следующий:

ArrayList<String> animals = new ArrayList<String>();
animals.add("bat");
animals.add("owl");
animals.add("bat");
animals.add("bat");

Как видите, animals ArrayList состоит из 3 bat элементов и одного owl элемента. Мне было интересно, есть ли какой-либо API в платформе Collection, который возвращает количество bat вхождений или есть другой способ определить количество вхождений.

Я обнаружил, что в Google Collection Multiset действительно есть API, который возвращает общее количество вхождений элемента. Но это совместимо только с JDK 1.5. Наш продукт в настоящее время находится в JDK 1.6, поэтому я не могу его использовать.

Ответы [ 21 ]

5 голосов
/ 18 марта 2016

Чтобы получить вхождения объекта из списка напрямую:

int noOfOccurs = Collections.frequency(animals, "bat");

Чтобы получить вхождение коллекции Object внутри списка, переопределите метод equals в классе Object следующим образом:

@Override
public boolean equals(Object o){
    Animals e;
    if(!(o instanceof Animals)){
        return false;
    }else{
        e=(Animals)o;
        if(this.type==e.type()){
            return true;
        }
    }
    return false;
}

Animals(int type){
    this.type = type;
}

Вызовите коллекцию. Частота как:

int noOfOccurs = Collections.frequency(animals, new Animals(1));
5 голосов
/ 03 февраля 2009

То, что вы хотите, это сумка - которая похожа на набор, но также подсчитывает количество случаев. К сожалению, фреймворк java Collections - великолепен, так как у него нет пакета Bag. Для этого необходимо использовать Apache Common Collection текст ссылки

2 голосов
/ 23 августа 2017
List<String> list = Arrays.asList("as", "asda", "asd", "urff", "dfkjds", "hfad", "asd", "qadasd", "as", "asda",
        "asd", "urff", "dfkjds", "hfad", "asd", "qadasd" + "as", "asda", "asd", "urff", "dfkjds", "hfad", "asd",
        "qadasd", "as", "asda", "asd", "urff", "dfkjds", "hfad", "asd", "qadasd");

Метод 1:

Set<String> set = new LinkedHashSet<>();
set.addAll(list);

for (String s : set) {

    System.out.println(s + " : " + Collections.frequency(list, s));
}

Метод 2:

int count = 1;
Map<String, Integer> map = new HashMap<>();
Set<String> set1 = new LinkedHashSet<>();
for (String s : list) {
    if (!set1.add(s)) {
        count = map.get(s) + 1;
    }
    map.put(s, count);
    count = 1;

}
System.out.println(map);
2 голосов
/ 04 февраля 2016

Java 8 - другой метод

String searched = "bat";
long n = IntStream.range(0, animals.size())
            .filter(i -> searched.equals(animals.get(i)))
            .count();
2 голосов
/ 29 января 2015

Если вы используете Eclipse Collections , вы можете использовать Bag. MutableBag может быть возвращено из любой реализации RichIterable путем вызова toBag().

MutableList<String> animals = Lists.mutable.with("bat", "owl", "bat", "bat");
MutableBag<String> bag = animals.toBag();
Assert.assertEquals(3, bag.occurrencesOf("bat"));
Assert.assertEquals(1, bag.occurrencesOf("owl"));

Реализация HashBag в EC поддерживается MutableObjectIntMap.

Примечание: Я являюсь коммиттером для Eclipse Collections.

1 голос
/ 03 февраля 2009

Поместите элементы массива в hashMap для подсчета частоты.

0 голосов
/ 31 августа 2016

Я не хотел усложнять этот случай и сделал это с двумя итераторами У меня есть HashMap с LastName -> FirstName. И мой метод должен удалять элементы с указателем FirstName.

public static void removeTheFirstNameDuplicates(HashMap<String, String> map)
{

    Iterator<Map.Entry<String, String>> iter = map.entrySet().iterator();
    Iterator<Map.Entry<String, String>> iter2 = map.entrySet().iterator();
    while(iter.hasNext())
    {
        Map.Entry<String, String> pair = iter.next();
        String name = pair.getValue();
        int i = 0;

        while(iter2.hasNext())
        {

            Map.Entry<String, String> nextPair = iter2.next();
            if (nextPair.getValue().equals(name))
                i++;
        }

        if (i > 1)
            iter.remove();

    }

}
0 голосов
/ 03 февраля 2009

Так сделайте это по старинке и сверните свое собственное:

Map<String, Integer> instances = new HashMap<String, Integer>();

void add(String name) {
     Integer value = instances.get(name);
     if (value == null) {
        value = new Integer(0);
        instances.put(name, value);
     }
     instances.put(name, value++);
}
0 голосов
/ 01 марта 2009

Если вы являетесь пользователем моего ForEach DSL , это можно сделать с помощью запроса Count.

Count<String> query = Count.from(list);
for (Count<Foo> each: query) each.yield = "bat".equals(each.element);
int number = query.result();
0 голосов
/ 07 февраля 2019
Map<String,Integer> hm = new HashMap<String, Integer>();
for(String i : animals) {
    Integer j = hm.get(i);
    hm.put(i,(j==null ? 1 : j+1));
}
for(Map.Entry<String, Integer> val : hm.entrySet()) {
    System.out.println(val.getKey()+" occurs : "+val.getValue()+" times");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...