使用Java中的HashMap查找字符串或整数列表的模式?

时间:2018-11-18 04:48:47

标签: java list hashmap mode

我已经在此代码上停留了几天了,我无法弄清楚。 getMedian方法可以正常工作,并打印出字符串列表和整数列表的中位数。我知道的getMode函数接近正确,但是我无法使其正常工作,并且我正在尝试使用HashMap使其正常工作。当前,除非我将getMode方法更改为“ int”,否则它将不会处于打印模式。最大的问题是让它像中位数一样输出字符串列表和整数列表的模式。我真的可以为此提供一些帮助。

/*
 * Accepts Array of String or Integer and provides methods to return the mode and median
*
*/

package stats;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ModeNMedianProblem<E>
{

 private final List<E> elements;

public ModeNMedianProblem(E[] items)
{
    elements = new ArrayList<>();
    elements.addAll(Arrays.asList(items));
}

private class GenericComparator implements Comparator<E>
{


    @Override
    public int compare(E o1, E o2)
    {
        if (o1.getClass() == Integer.class)
        {
            Integer v1 = (Integer)o1;
            Integer v2 = (Integer)o2;
            return v1.compareTo(v2);
        }
        else if (o1.getClass() == String.class)
        {
            String v1 = (String)o1;
            String v2 = (String)o2;
            return v1.compareTo(v2);
        }
        else 
        {
            throw new IllegalArgumentException("Classes of type " + o1.getClass().toGenericString() + " are not supported.");
        }
    }
}


/**
 *
 * @param args
 * @return
 */
public List<E> getSortedList() 
{ 
    Collections.sort(elements,new GenericComparator());
    return elements;
}

public E getMedian() {

    int half = elements.size() / 2;
    return elements.get(half);        
}

public E getMode() {

    Map<E,Integer> freq = new HashMap<>();


    int mode = 0, maxCount = 0;
    int length = freq.size();

    for (int i = 0; i < length; ++i) 
    {
        int count = 0;
        for (int j = 0; j < length; ++j) 
        {
            if (freq.get(i) == freq.get(j)) 
                ++count;

            if (count > maxCount) 
            {
            maxCount = count;
            mode = freq.get(i);
            }
        }           
    }
    return mode;
}


/**
 * @param args the command line arguments
 */
public static void main(String[] args)
{
    String[] s = {"and","an","the","my","but","may","an","the","the"};
    Integer[] x = {1,5,9,2,4,3,7,100,2};

    ModeNMedianProblem mn1 = new ModeNMedianProblem(s);
    System.out.println("List: " + mn1.getSortedList());
    System.out.println("Median: " + mn1.getMedian());
    System.out.println("Mode: " + mn1.getMode());

    mn1 = new ModeNMedianProblem(x);
    System.out.println("List: " + mn1.getSortedList());
    System.out.println("Median: " + mn1.getMedian());
    System.out.println("Mode: " + mn1.getMode());

}

}

1 个答案:

答案 0 :(得分:1)

您必须更改getMode方法以使用源集合elements并计算模式。下面提供了一种使用Java8的实现。

public E getMode() {
    Map<E, Long> elementToCount = elements.stream()
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    return elementToCount.entrySet().stream().max(Map.Entry.comparingByValue()).map(Map.Entry::getKey)
            .orElseThrow(IllegalArgumentException::new);
}

这里要考虑的另一点是,您已经在main方法中使用了原始类型。首选使用泛型类型而不是原始类型,因为它可以确保编译时类型的安全性。我建议您像这样更改主要方法以使用泛型类型。

public static void main(String[] args) {
    String[] s = { "and", "an", "the", "my", "but", "may", "an", "the", "the" };
    Integer[] x = { 1, 5, 9, 2, 4, 3, 7, 100, 2 };

    ModeNMedianProblem<String> mn1 = new ModeNMedianProblem<>(s);
    System.out.println("List: " + mn1.getSortedList());
    System.out.println("Median: " + mn1.getMedian());
    System.out.println("Mode: " + mn1.getMode());

    ModeNMedianProblem<Integer> mn2 = new ModeNMedianProblem<>(x);
    System.out.println("List: " + mn2.getSortedList());
    System.out.println("Median: " + mn2.getMedian());
    System.out.println("Mode: " + mn2.getMode());

}

进行建议的更改后,您应该得到以下结果。

List: [an, an, and, but, may, my, the, the, the]
Median: may
Mode: the
List: [1, 2, 2, 3, 4, 5, 7, 9, 100]
Median: 4
Mode: 2