从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序:
1,张三,28
2,李四,35
3,张三,28
4,王五,35
5,张三,28
6,李四,35
7,赵六,28
8,田七,35
package com.huawei.interview;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeSet;
public class GetNameTest {
public static void main(String[] args) {
// 创建一个HashMap来存储处理文件后的结果
Map<String, Integer> results = new HashMap<>();
// 从与该类相同的包中加载资源文件'info.txt'
InputStream ips = GetNameTest.class.getResourceAsStream("info.txt");
// 使用BufferedReader包装InputStream,以逐行读取文件
BufferedReader in = new BufferedReader(new InputStreamReader(ips));
// 变量用于存储从文件中读取的每一行
String line = null;
try {
// 逐行读取文件直到文件末尾
while((line = in.readLine()) != null) {
// 处理每一行并更新结果Map
dealLine(line, results);
}
// 对结果进行排序并打印
sortResults(results);
} catch (IOException e) {
// 如果发生I/O错误,打印堆栈跟踪
e.printStackTrace();
}
}
// 内部类,用于表示具有姓名和数值的用户
static class User {
public String name;
public Integer value;
public User(String name, Integer value) {
this.name = name;
this.value = value;
}
@Override
public boolean equals(Object obj) {
// 重写equals方法,但在此示例中未使用
boolean result = super.equals(obj);
System.out.println(result);
return result;
}
}
private static void sortResults(Map<String, Integer> results) {
// 使用TreeSet根据定义的比较器来存储排序的用户对象
TreeSet<User> sortedResults = new TreeSet<>(
new Comparator<User>() {
// 比较器,用于按值排序用户,如果值相等则按姓名排序
public int compare(User user1, User user2) {
if(user1.value < user2.value) {
return -1;
} else if(user1.value > user2.value) {
return 1;
} else {
return user1.name.compareTo(user2.name);
}
}
}
);
// 遍历结果Map中的键
Iterator<String> iterator = results.keySet().iterator();
while(iterator.hasNext()) {
String name = iterator.next();
Integer value = results.get(name);
// 仅当值大于1时,才将用户添加到排序集合中
if(value > 1) {
sortedResults.add(new User(name, value));
}
}
// 打印排序结果
printResults(sortedResults);
}
private static void printResults(TreeSet<User> sortedResults) {
// 遍历排序后的用户对象,并打印它们的姓名和数值
Iterator<User> iterator = sortedResults.iterator();
while(iterator.hasNext()) {
User user = iterator.next();
System.out.println(user.name + ":" + user.value);
}
}
public static void dealLine(String line, Map<String, Integer> map) {
// 处理每一行,如果行不为空
if(!"".equals(line.trim())) {
// 按逗号分割每一行
String[] results = line.split(",");
// 检查分割后的行是否正好有3部分
if(results.length == 3) {
String name = results[1];
// 从Map中获取该姓名当前的值,如果没有则默认为0
Integer value = map.get(name);
if(value == null) value = 0;
// 增加该姓名的计数,并将其放回Map
map.put(name, value + 1);
}
}
}
}
详细解释:
-
导入部分:
- 导入必要的Java库,包括用于读取文件的I/O库以及用于数据结构和比较的实用程序类。
-
主方法:
- 主方法是程序的入口点。它初始化一个
HashMap
来存储结果。 - 使用
getResourceAsStream
从相同包中读取文件info.txt
。 - 使用
dealLine
方法处理文件的每一行,并将结果存储在Map中。 - 在处理完所有行后,使用
sortResults
方法对结果进行排序并打印。
- 主方法是程序的入口点。它初始化一个
-
User类:
User
类是一个简单的数据结构,用于存储用户的姓名和数值。- 重写了
equals
方法,但在此示例中未使用。
-
sortResults方法:
- 该方法对存储在Map中的结果进行排序。
- 使用带有自定义比较器的
TreeSet
按值和姓名排序User
对象。 - 仅将值大于1的用户添加到排序集合中。
- 使用
printResults
方法打印排序结果。
-
printResults方法:
- 遍历排序后的
TreeSet
并打印每个用户的姓名和数值。
- 遍历排序后的
-
dealLine方法:
- 处理文件的每一行。
- 按逗号分割每一行,并检查是否正好有3部分。
- 更新Map中每个姓名的计数。