从Java中的2个文件中打印匹配信息

时间:2018-05-07 19:05:50

标签: java file

我正在尝试编写一个检查两个文件的程序,并从这两个文件中打印出公共内容。

文件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来仅打印学生姓名及其专业。感谢您的帮助。

5 个答案:

答案 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}

注意:

  1. 我在classes.txt和names.txt中添加了故意无法匹配的键,因此您会看到它没有出现在输出中。这是因为密钥永远不会进入commonKeys集。因此,它们永远不会插入到连接的地图中。

  2. 如果您想要我的来电map.entrySet()

  3. ,您可以循环浏览HashMap