按属性

时间:2017-12-04 21:51:26

标签: java arrays parsing collections

所以基本上有人给了我一个文本文件供我阅读Java,我必须打印出它的某些部分。

所以我做的是将所有文本文件放入String,每个单词之间都有一个":"。因此,我使用":"函数将所有文本与split分开。起初每一行都是这样的

firstName:Surname:Age:Country
firstName:Surname:Age:Country
firstName:Surname:Age:Country
firstName:Surname:Age:Country
firstName:Surname:Age:Country
firstName:Surname:Age:Country
firstName:Surname:Age:Country
firstName:Surname:Age:Country

在没有冒号的情况下会是同样的事情。

现在如果我说all[0],我会全部 firstNames

我想要的是获得前3名最高年龄,但我不知道该怎么做。

1 个答案:

答案 0 :(得分:1)

说明

假设您有一个包含

等行的文件
John:Doe:20:USA
Jane:Doe:35:Germany
Robert:Moe:14:Japan
Larry:Loe:25:China
Richard:Roe:27:India

你希望3行具有最高年龄,即

Jane:Doe:35:Germany
Richard:Roe:27:India
Larry:Loe:25:China

程序很简单。首先读取所有行,按:拆分并将数据解析为包含类Person的类。将它们收集到像List<Person>这样的集合中,并使用比较年龄的Comparator对它们进行排序。或者,您可以让Person实施Comparable,然后使用他们的自然顺序。

如果效率很重要,您也可以部分排序,因为您只对前3次点击感兴趣。为此,您可以使用PriorityQueue,插入所有元素并调用poll三次。

解决方案

首先是Person包装类

public class Person {
    private String mFirstName;
    private String mSurname;
    private int mAge;
    private String mCountry;

    public Person(String firstName, String surname, int age, String country) {
        this.mFirstName = firstName;
        this.mSurname = surname;
        this.mAge = age;
        this.mCountry = country;
    }

    // TODO Some getters

    public String toString() {
        return this.mFirstName + ":" + this.mSurname
            + ":" + this.mAge + ":" + this.mCountry;
    }

    public static Person parse(String[] data) {
        String firstName = data[0];
        String surname = data[1];
        int age = Integer.parseInt(data[2]);
        String country = data[3];

        return new Person(firstName, surname, age, country);
    }
}

接下来,我们读取所有行,拆分数据并将其解析为Person。之后,我们将结果排序并限制为3。最后,我们收集到List并打印结果。

Path file = Paths.get(...);
Pattern separator = Pattern.compile(":");

List<Person> persons = Files.lines(file) // Stream<String>
    .map(separator::splitAsStream)       // Stream<String[]>
    .map(Person::parse)                  // Stream<Person>
    .sorted(Comparator.comparingInt(Person::getAge).reversed())
    .limit(3)
    .collect(Collectors.toList());

persons.forEach(System.out::println);

或者如果您想按照建议使用PriorityQueue,这将改善运行时间:

Path file = Paths.get(...);
Pattern separator = Pattern.compile(":");

PriorityQueue<Person> personQueue = Files.lines(file)
    .map(separator::splitAsStream)
    .map(Person::parse)
    .collect(Collectors.toCollection(() -> {
        return new PriorityQueue<>(
            Comparator.comparingInt(Person::getAge).reversed());
    }));

List<Person> persons = new ArrayList<>(3);
persons.add(personQueue.poll());
persons.add(personQueue.poll());
persons.add(personQueue.poll());

persons.forEach(System.out::println);