版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
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 的个数”。
- 第一个网页:
【一道面试题】用面向对象的方法求出数组中重复 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、代码中
new
的HashMap
改为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 次