Java在HashSet中找到最常见的值

Java在HashSet中找到最常见的值,java,jakarta-ee,hashset,Java,Jakarta Ee,Hashset,好的,这是一个基本的问题,但我想知道最好的方法是什么 我有一个要向其中添加对象的哈希集,.add()方法只会在对象不存在时添加对象。但我要做的是添加所有对象,然后在最后得到以下结果 -唯一(不同)对象的数量 -物体的平均频率 有人能给我指出正确的方向吗 提前感谢不同对象的数量将只是随后散列集的大小 根据您所说的“平均频率”的含义,您可能对source.size()/set.size()。。。(如果需要,可以将其中一个操作数强制转换为double,以强制进行浮点运算)。如果您能通过一些示例详细说明

好的,这是一个基本的问题,但我想知道最好的方法是什么

我有一个要向其中添加对象的哈希集,.add()方法只会在对象不存在时添加对象。但我要做的是添加所有对象,然后在最后得到以下结果

-唯一(不同)对象的数量
-物体的平均频率

有人能给我指出正确的方向吗


提前感谢

不同对象的数量将只是随后散列集的大小


根据您所说的“平均频率”的含义,您可能对
source.size()/set.size()
。。。(如果需要,可以将其中一个操作数强制转换为
double
,以强制进行浮点运算)。如果您能通过一些示例详细说明您需要什么,我们可能会提供更多帮助。

使用HashMap。使用这些条目作为键,并将它们映射到整数以保持计数

编辑:您可能希望包装HashMap,以确保每次添加或删除对象时,都会适当修改计数器。
要开始,请执行以下操作:

class MapWrapper<Key>
{
    private Map<Key,Integer> map = new HashMap<Key, Integer>();

    void add( Key key )
    {
        Integer n = map.get( key );
        if ( n == null )
        {
            map.put( key, 1 );
        }
        else
        {
            map.put( key, new Integer( n + 1 ));
        }
    }

    int occurrences( Key k )
    {
        Integer n = map.get( k );
        if ( n == null )
        {
            return 0;
        }
        else
        {
            return n;
        }
    }
}
类映射包装器
{
私有映射映射=新的HashMap();
无效添加(键)
{
整数n=map.get(key);
如果(n==null)
{
地图放置(图例1);
}
其他的
{
put(key,新整数(n+1));
}
}
整数出现次数(键k)
{
整数n=map.get(k);
如果(n==null)
{
返回0;
}
其他的
{
返回n;
}
}
}
您可以只使用(散列)映射,而不是将每个不同对象的计数保留为映射中的值,也可以继续使用集合,但在某处对所有要添加的调用进行计数


插入的对象总数是您计算的值或映射中所有值的总和(在EntrySet上迭代)。不同对象的数量始终是地图/集合的大小(),平均频率显然是商。

对于这种情况,我使用自己的地图界面实现:

/*
* Providers easily work with maps of lists
* */
public interface ManyValuedMap<K, V> extends Cloneable, Map<K, List<V>>, Serializable{

    public List<V> put(K key, V... values);
    public void clear(K key);
    public ManyValuedMap<K, V> clone();
    public void sort(Comparator<? super V> c);
    public List<V> getAllValues();
    public Collection<List<V>> values(Comparator<? super K> c);
    public void lock();
    public Map<K, List<V>> toMap();

}
/*
*提供者可以轻松地处理列表的映射
* */
公共接口ManyValuedMap扩展了可克隆、映射、可序列化{
公共列表put(K键,V…值);
公共空白清除(K键);
公共多值映射克隆();
public void sort(ComparatorGuava)是一个方便的选择。例如:

HashMultiset<String> multiSet = HashMultiset.create();
multiSet.add("a");
multiSet.add("a");
multiSet.add("b");

Assert.assertEquals(2, multiSet.count("a"));//count "a" 
Assert.assertEquals(3, multiSet.size());//set size
Assert.assertEquals(2, multiSet.elementSet().size());//unique (distinct) size 
HashMultiset multiSet=HashMultiset.create();
多集。添加(“a”);
多集。添加(“a”);
多组添加(“b”);
Assert.assertEquals(2,multiSet.count(“a”);//count“a”
Assert.assertEquals(3,multiSet.size());//设置大小
Assert.assertEquals(2,multiSet.elementSet().size());//唯一(不同)大小
不太适合跟踪单个计数,但几乎是完美的

import java.util.HashMap;
import java.util.Map;

public class Count<K, V> extends HashMap<K, V> {

    // Counts unique objects
    public void add(K o) {
        int count = this.containsKey(o) ? ((Integer)this.get(o)).intValue() + 1 : 1;
        super.put(o, (V) new Integer(count));
    }

    // Demonstration
    public static void main(String[] args) {

        Count<Object, Integer> c = new Count<Object, Integer>();

        String one = "one";
        String two = "two";
        String six = "six";

        c.add(one);
        c.add(two);
        c.add(two);
        c.add(six);
        c.add(six);
        c.add(six);

        System.out.println("Number of distinct objects: " + c.size());

        System.out.println("Frequency of different objects: ");

        for (Map.Entry<Object, Integer> entry : c.entrySet()) {
            System.out.println(entry.getKey() + " - " + entry.getValue());
        }
    }
}

乔恩,你太直白了。OP实际上是指一张地图,而不是一套。他的意图很明确。他的方法很幼稚。@Bohemian:老实说,我现在还不清楚这个意图。我们知道OP真的需要每件物品的数量吗?@Jon我指的是普通物品的平均数量objects@DaveB:那么这和“对象总数除以不同对象的数量”?我听起来像是这样,但我可能错了。这会给出平均数,但如果你想要模式或中间值,那是另一回事。@Jon yes“重复对象的平均数”我会删除containsKey检查,只需调用get()然后检查它是否返回null。这避免了执行两次查找。不客气。还要注意这一点。或者,Apache Commons集合中有一个。这正是我想要的……要找到平均值,有没有比只遍历映射更有效的方法?@DaveB:你真的需要单个计数吗是吗?如果是这样,这绝对是正确的方法。如果不是,我想我的方法就是你想要的。@DaveB-这个片段输出单个对象的频率,而不是。说到效率,那么一个简单的
for
循环就是O(n)这是非常有效的。此外,如果没有某种迭代,读取动态映射的所有条目是不可能的。
import java.util.HashMap;
import java.util.Map;

public class Count<K, V> extends HashMap<K, V> {

    // Counts unique objects
    public void add(K o) {
        int count = this.containsKey(o) ? ((Integer)this.get(o)).intValue() + 1 : 1;
        super.put(o, (V) new Integer(count));
    }

    // Demonstration
    public static void main(String[] args) {

        Count<Object, Integer> c = new Count<Object, Integer>();

        String one = "one";
        String two = "two";
        String six = "six";

        c.add(one);
        c.add(two);
        c.add(two);
        c.add(six);
        c.add(six);
        c.add(six);

        System.out.println("Number of distinct objects: " + c.size());

        System.out.println("Frequency of different objects: ");

        for (Map.Entry<Object, Integer> entry : c.entrySet()) {
            System.out.println(entry.getKey() + " - " + entry.getValue());
        }
    }
}
Number of distinct objects - 3
Frequency of different objects:
two - 2
one - 1
six - 3