我正在尝试编写一个检查两个文件的程序,并从这两个文件中打印出公共内容。
文件1内容的示例为:
James 1
Cody 2
John 3
文件2内容的示例为:
1 Computer Science
2 Chemistry
3 Physics
因此,控制台上打印的最终输出将是:
James Computer Science
Cody Chemistry
John Physics
以下是我目前在代码中的内容:
public class Filereader {
public static void main(String[] args) throws Exception {
File file = new File("file.txt");
File file2 = new File("file2.txt");
BufferedReader reader = new BufferedReader(new FileReader(file));
BufferedReader reader2 = new BufferedReader(new FileReader(file2));
String st, st2;
while ((st = reader.readLine()) != null) {
System.out.println(st);
}
while ((st2 = reader2.readLine()) != null) {
System.out.println(st2);
}
reader.close();
reader2.close();
}
}
我无法确定如何匹配文件内容,并通过匹配每个文件中的学生ID来仅打印学生姓名及其专业。感谢您的帮助。
答案 0 :(得分:1)
您可以使用其他答案并为每个文件创建一个对象,例如数据库中的表。
public class Person{
Long id;
String name;
//getters and setters
}
public class Course{
Long id;
String name;
//getters and setters
}
您对列有更多控制,并且使用起来很简单。
此外,您将使用ArrayList<Person>
和ArrayList<Course>
,您的关系可以是对象中的变量,例如courseId
类中的Person
或其他内容。
if(person.getcourseId() == course.getId()){
...
}
如果匹配是第一个文件数,则使用person.getId() == course.getId()
。
Ps:不在您的情况下使用split(" ")
,因为您可以使用其他具有两个值的对象,即1 Computer Science
。
答案 1 :(得分:0)
您应该按顺序同时阅读这些文件。使用单个while
语句很容易实现这一点。
while ((st = reader.readLine()) != null && (st2 = reader2.readLine()) != null) {
// print both st and st2
}
现在编写代码的方式,它一次读取一个文件,从每个单独的文件向控制台打印数据。如果要将结果合并在一起,则必须在单个循环中组合文件的输出。
鉴于意图也可能是您在一个批次中有一个奇数大小的文件,但您确实有数字要关联,或者数字可能以非顺序顺序排列,您可能希望将这些结果存储到数据中结构,就像List
一样,因为您知道每个值的具体索引并知道它们应该适合的位置。
答案 2 :(得分:0)
您想要的是将文本文件数据组织到地图中,然后合并他们的数据。即使您的数据是混合的,也不按顺序,这将有效。
public class Filereader {
public static void main(String[] args) throws Exception {
File file = new File("file.txt");
File file2 = new File("file2.txt");
BufferedReader reader = new BufferedReader(new FileReader(file));
BufferedReader reader2 = new BufferedReader(new FileReader(file2));
String st, st2;
Map<Integer, String> nameMap = new LinkedHashMap<>();
Map<Integer, String> majorMap = new LinkedHashMap<>();
while ((st = reader.readLine()) != null) {
System.out.println(st);
String[] parts = st.split(" "); // Here you got ["James", "1"]
String name = parts[0];
Integer id = Integer.parseInt(parts[1]);
nameMap.put(id, name);
}
while ((st2 = reader2.readLine()) != null) {
System.out.println(st2);
String[] parts = st2.split(" ");
String name = parts[1];
Integer id = Integer.parseInt(parts[0]);
majorMap.put(id, name);
}
reader.close();
reader2.close();
// Combine and print
nameMap.keySet().stream().forEach(id -> {
System.out.println(nameMap.get(id) + " " + majorMap.get(id));
})
}
}
答案 3 :(得分:0)
结合NIO文件和流API,它有点简单:
public static void main(String[] args) throws Exception {
Map<String, List<String[]>> f1 = Files
.lines(Paths.get("file1"))
.map(line -> line.split(" "))
.collect(Collectors.groupingBy(arr -> arr[1]));
Map<String, List<String[]>> f2 = Files
.lines(Paths.get("file2"))
.map(line -> line.split(" "))
.collect(Collectors.groupingBy(arr -> arr[0]));
Stream.concat(f1.keySet().stream(), f2.keySet().stream())
.distinct()
.map(key -> f1.get(key).get(0)[0] + " " + f2.get(key).get(0)[1])
.forEach(System.out::println);
}
在代码中很容易注意到,有两个文件之间存在一致性的有效数据假设。如果这不成立,您可能需要先运行过滤器以排除任一文件中缺少的条目:
Stream.concat(f1.keySet().stream(), f2.keySet().stream())
.filter(key -> f1.containsKey(key) && f2.containsKey(key))
.distinct()
...
答案 4 :(得分:0)
如果您更改顺序,使得这两个文件中的数字首先出现,您可以将这两个文件读入HashMap,然后创建一组公共密钥。然后遍历公共密钥集并从每个Hashmap中获取相关值以进行打印:
我的解决方案很冗长,但我这样编写,以便您可以准确地看到发生了什么。
import java.util.Set;
import java.util.HashSet;
import java.util.Map;
import java.util.HashMap;
import java.io.File;
import java.util.Scanner;
class J {
public static Map<String, String> fileToMap(File file) throws Exception {
// TODO - Make sure the file exists before opening it
// Scans the input file
Scanner scanner = new Scanner(file);
// Create the map
Map<String, String> map = new HashMap<>();
String line;
String name;
String code;
String[] parts = new String[2];
// Scan line by line
while (scanner.hasNextLine()) {
// Get next line
line = scanner.nextLine();
// TODO - Make sure the string has at least 1 space
// Split line by index of first space found
parts = line.split(" ", line.indexOf(' ') - 1);
// Get the class code and string val
code = parts[0];
name = parts[1];
// Insert into map
map.put(code, name);
}
// Close input stream
scanner.close();
// Give the map back
return map;
}
public static Set<String> commonKeys(Map<String, String> nameMap,
Map<String, String> classMap) {
Set<String> commonSet = new HashSet<>();
// Get a set of keys for both maps
Set<String> nameSet = nameMap.keySet();
Set<String> classSet = classMap.keySet();
// Loop through one set
for (String key : nameSet) {
// Make sure the other set has it
if (classSet.contains(key)) {
commonSet.add(key);
}
}
return commonSet;
}
public static Map<String, String> joinByKey(Map<String, String> namesMap,
Map<String, String> classMap,
Set<String> commonKeys) {
Map<String, String> map = new HashMap<String, String>();
// Loop through common keys
for (String key : commonKeys) {
// TODO - check for nulls if get() returns nothing
// Fetch the associated value from each map
map.put(namesMap.get(key), classMap.get(key));
}
return map;
}
public static void main(String[] args) throws Exception {
// Surround in try catch
File names = new File("names.txt");
File classes = new File("classes.txt");
Map<String, String> nameMap = fileToMap(names);
Map<String, String> classMap = fileToMap(classes);
Set<String> commonKeys = commonKeys(nameMap, classMap);
Map<String, String> nameToClass = joinByKey(nameMap, classMap, commonKeys);
System.out.println(nameToClass);
}
}
names.txt中
1 James
2 Cody
3 John
5 Max
classes.txt
1 Computer Science
2 Chemistry
3 Physics
4 Biology
输出:
{Cody=Chemistry, James=Computer, John=Physics}
注意:
我在classes.txt和names.txt中添加了故意无法匹配的键,因此您会看到它没有出现在输出中。这是因为密钥永远不会进入commonKeys
集。因此,它们永远不会插入到连接的地图中。
如果您想要我的来电map.entrySet()