【Java面试题】用面向对象的方法求出数组中重复 value 的个数

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_44591035/article/details/97542021

Java Map相关

来源: 黑马程序员的《Java面试宝典(Beta6.0)》二八8.4跟数组相关的面试题

一、原内容

用面向对象的方法求出数组中重复 value 的个数,按如下个数输出:
1 出现:1 次
3 出现:2 次
8 出现:3 次
2 出现:4 次
int[] arr = {1,4,1,4,2,5,4,5,8,7,8,77,88,5,4,9,6,2,4,1,5};

二、分析

1、先问度娘:“用面向对象的方法求出数组中重复 value 的个数”。

public class RepeatNum {
	public static void main(String[] args) {
		int[] arr = {1,4,1,4,2,5,4,5,8,7,8,77,88,5,4,9,6,2,4,1,5};
		int[] num = new int[124];
		for(int i=0;i<arr.length;i++){
			num[arr[i]]++;
		}
		for(int j=0; j<num.length;j++) {
			if(num[j] != 0) {
				System.out.println(j+"出现了"+num[j]+"次");
			}
		}
	}
}
  • 简单粗暴,但没有用面向对象的方法哈!

2、使用Map来解决。

题中的输出结果是两两数据的对应关系,自然就会想到Map中的映射关系。还要考虑的一点就是key和value的排序问题,题中很明显是按照value进行排序的。
这里,为了举一反三,我总结了按键和值排列的以下几种情况,即:

  • (1)无排序 (2)按key升序 (3)按value升序 (4)按value升序后,再按key升序

三、源代码

1、无排序

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

public class Test1 {
    public static void main(String[] args) {
        int[] arr = {1, 4, 1, 4, 2, 5, 4, 5, 8, 7, 8, 77, 88, 5, 4, 9, 6, 2, 4, 1, 5};                
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        
        //循环数组
        for (int i : arr) {
            Integer temp = map.get(i);
            //判断当前数字是否已经统计过。如果统计过,取出出现的次数,加1;否则给1
            int v = ((temp != null) ? (temp.intValue() + 1) : 1);
            map.put(i, v);
        }
        
        for (Map.Entry<Integer, Integer> entry : map.entrySet()) { 
               System.out.println(entry.getKey() + " 出现:" + entry.getValue() + " 次"); 
          } 
    }
}
  • 控制台输出:
    1 出现:3 次
    2 出现:2 次
    4 出现:5 次
    5 出现:4 次
    6 出现:1 次
    7 出现:1 次
    8 出现:2 次
    88 出现:1 次
    9 出现:1 次
    77 出现:1 次

2、按key升序

  • 仅仅将上面1、代码中newHashMap改为TreeMap即可。
  • TreeMap就是按key值升序构建。
  • 改后再Run,控制台输出:
    1 出现:3 次
    2 出现:2 次
    4 出现:5 次
    5 出现:4 次
    6 出现:1 次
    7 出现:1 次
    8 出现:2 次
    9 出现:1 次
    77 出现:1 次
    88 出现:1 次

3、按value升序

  • 还是在上面1、代码基础上,将Map数据转换为List,然后就可以利用集合本身的排序方法了。
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class Test3 {
    public static void main(String[] args) {
        int[] arr = {1, 4, 1, 4, 2, 5, 4, 5, 8, 7, 8, 77, 88, 5, 4, 9, 6, 2, 4, 1, 5};
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        
        for (int i : arr) {
            Integer temp = map.get(i);
            int v = ((temp != null) ? (temp.intValue() + 1) : 1);
            map.put(i, v);
        }
        
        //这里将map.entrySet()转换成list
        List<Map.Entry<Integer, Integer>> list = new ArrayList<Map.Entry<Integer, Integer>>(map.entrySet());
        //然后通过比较器来实现排序
        Collections.sort(list,new Comparator<Map.Entry<Integer, Integer>>() {
            //升序排序
            public int compare(Entry<Integer, Integer> o1,
                    Entry<Integer, Integer> o2) {
                return o1.getValue() - o2.getValue();
            }
            
        });
        
        for (Map.Entry<Integer, Integer> mapping : list) { 
               System.out.println(mapping.getKey() + " 出现:" + mapping.getValue() + " 次"); 
          } 
    }

}
  • 控制台输出:
    6 出现:1 次
    7 出现:1 次
    88 出现:1 次
    9 出现:1 次
    77 出现:1 次
    2 出现:2 次
    8 出现:2 次
    1 出现:3 次
    5 出现:4 次
    4 出现:5 次

4、按value升序后,再按key升序

  • 在上面3、代码基础上,改一改其中比较器的compare()函数,多增加一个条件即可。改成如下:
  public int compare(Entry<Integer, Integer> o1,
          Entry<Integer, Integer> o2) {
      int vc = o1.getValue() - o2.getValue(); //vc:value compare
      return (vc != 0) ? vc : (o1.getKey() - o2.getKey());
  }
  • 改后再Run,控制台输出:
    6 出现:1 次
    7 出现:1 次
    9 出现:1 次
    77 出现:1 次
    88 出现:1 次
    2 出现:2 次
    8 出现:2 次
    1 出现:3 次
    5 出现:4 次
    4 出现:5 次

四、原理知识等有参考如下博客:

猜你喜欢

转载自blog.csdn.net/weixin_44591035/article/details/97542021
今日推荐