如何使用整数数组元素填充LinkedHashMap并使用key作为计数器

时间:2017-06-24 21:03:44

标签: java arrays

我需要接受一个整数(maxInstances)和一个整数数组作为参数。然后我需要消除数组中出现超过maxInstances的元素并返回结果。注意:结果必须保持与原始数组相同的顺序,因此使用LinkedHashMap。由于我的Java生锈,我遇到了一些麻烦。这是我到目前为止的代码,但这似乎只在LinkedHashMap中生成一个键值对。所以我现在就被困在这里。 :(我没有得到我用删除元素制作新数组的部分,所以返回只是一个占位符。欢迎所有想法!

public static int[] answer(int[] data, maxInstances n) {
  if (data.length >= 100) {
   throw new IllegalArgumentException
    ("Too many IDs!");
  } else {
    int[] possibleNumbers = new int[100];
    LinkedHashMap<Integer, Integer> result = new LinkedHashMap<Integer, Integer>();

    for (int i = 0; i < data.length; ++i) {
      possibleNumbers[data[i]] = possibleNumbers[data[i]] + 1;
      result.put(data[i], possibleNumbers[data[i]]);

      // Get a set of the entries
      Set set = result.entrySet();

      // Get an iterator
      Iterator y = set.iterator();

      // Display elements
      while(y.hasNext()) {
         Map.Entry me = (Map.Entry)y.next();
         System.out.print(me.getKey() + ": ");
         System.out.println(me.getValue());
      }
      System.out.println();

    return data;
}

3 个答案:

答案 0 :(得分:2)

这是我的看法。如果你想返回一个数组,你真的不需要LinkedHashMap - 只需使用输入数组来驱动订单。

public static int [] answer (int [] data, final int maxInstances)
{
    if (data.length >= 100)
    {
        throw new IllegalArgumentException("Too many IDs!");
    }
    else
    {
        // build a frequency map
        Map<Integer, Integer> frequencyMap = new HashMap<>();
        for (int e : data)
        {
            Integer val = frequencyMap.get(e);
            if (val == null)
                frequencyMap.put(e, 1);
            else
                frequencyMap.put(e, val + 1);
        }

        // build a list with the values that appear no more than maxInstances
        List<Integer> newData = new ArrayList<>();
        for (int e : data)
        {
            if (frequencyMap.get(e) <= maxInstances)
                newData.add(e);
        }

        // convert the list to an int []
        int [] ret = new int[newData.size()];
        for (int i = 0; i < ret.length; i++)
            ret[i] = newData.get(i);

        return ret;
    }
}

<强>用法

public static void main (String [] args)
{
    int [] data = { 1, 2, 1, 5, 2, 3, 1 };
    int [] ret = answer(data, 2);

    // no 1s will be present in the output
    System.out.println(Arrays.toString(ret));
}

<强>输出

[2, 5, 2, 3]

答案 1 :(得分:0)

我猜你的主要问题不是生锈的java,而是生锈的算法思维。 如果我正确理解您的问题,您可以使用任何地图。输入表中的数字应用作键。此映射的值应用作计数器。如果未找到密钥,则应添加新项目以使用值1进行映射。如果找到,则应增加值。如果value不大于maxInstances那么你应该将input元素附加到带有结果的列表

答案 2 :(得分:0)

使用Java 8功能,您可以迭代数组并创建一个存储每个元素计数的映射。然后,再次迭代数组并仅保留计数小于或等于给定maxInstances值的元素:

public static int[] answer(int[] data, int maxInstances) {

    Map<Integer, Integer> map = new HashMap<>();

    Arrays.stream(data).forEach(n ->
        map.merge(n, 1, (a, b) -> a + b));

    return Arrays.stream(data)
        .filter(n -> map.get(n) <= maxInstances)
        .toArray();
}

用法:

int[] result = answer(new int[]{1, 2, 3, 3, 3, 2, 1, 0, 3}, 3);

System.out.println(Arrays.toString(result)); // [1, 2, 2, 1, 0]

这是一个使用jdk的收集器来创建计数图的变体:

public static int[] answer(int[] data, int maxInstances) {

    Map<Integer, Long> map = Arrays.stream(data)
        .boxed()
        .collect(Collectors.groupingBy(
            Function.identity(),
            Collectors.counting()));

    return Arrays.stream(data)
        .filter(n -> map.get(n) <= maxInstances)
        .toArray();
}