将文件内容复制到链表数组中并对其进行排序

时间:2013-02-13 01:04:52

标签: java arrays oop sorting linked-list

我有一个包含逗号分隔的文件 员工姓名,公司,年。

员工可能隶属于多家公司。

例如,

  

约翰,谷歌,2
  约翰,微软,1个
  詹姆斯,特斯拉,1个
  詹姆斯,苹果,5

我已使用java扫描程序检索信息

scanner.useDelimiter(",|\\n");
    while (scanner.hasNext()) {
        String line = scanner.next()

我是Java的新手,我正在尝试使用链接列表数组或数组数组以排序顺序(使用经验作为排序标准)插入上述内容。所以

员工 - > Company1 - >公司2 ....(按员工经验排序)

所以在上面的例子中,它将是:

  

John-> Microsoft->谷歌
  James-> Tesla->苹果

有人能指出我正确的方向吗?

注意:如果经验相同,那么哪家公司首先出现并不重要。

3 个答案:

答案 0 :(得分:1)

将此类用于Person

公共类人员{

@Getter @Setter
private String name;

@Getter @Setter
private TreeMap<String, String> companyExperience;

public Person(){
    companyExperience = new TreeMap<String, String>();
}

}

将经验用作TreeMap中的键将自动按升序为公司排序。

你的主要课程看起来像这样

public class App 
{
    public static void main( String[] args )
    {
        HashMap<String, Person> persons = new HashMap<String, Person>();

        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader("C:\\Users\\Public Administrator\\test.txt"));
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String line = null;

        try {
            while ((line = br.readLine()) != null) {
                String[] fields = line.split(",");
                String personName = fields[0];
                Person existingPerson = persons.get(personName);
                if (existingPerson==null){
                    Person newPerson = new Person();
                    newPerson.setName(personName);
                    newPerson.getCompanyExperience().put(Integer.parseInt(fields[2])+fields[1], fields[1]);
                    persons.put(personName, newPerson);
                } else{
                    existingPerson.getCompanyExperience().put(Integer.parseInt(fields[2])+fields[1], fields[1]);
                }
             }
        } catch (NumberFormatException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }    

        //output
        Iterator<Map.Entry<String, Person>> entries = persons.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry<String, Person> entry = entries.next();
            Person _person = entry.getValue();
            System.out.print(_person.getName());

            Iterator<Map.Entry<String, String>> companyExperiences = _person.getCompanyExperience().entrySet().iterator();
            while (companyExperiences.hasNext()) {
                Map.Entry<String, String> companyExperience = companyExperiences.next();

                System.out.print(" > "+companyExperience.getValue());
            }
            System.out.println();

        }
    }
}

我测试了它,看起来很漂亮,对我很好。

顺便说一句,@ Getter和@Setter注释来自Lombok项目。您既可以使用它,也可以创建自己的getter / setter。

答案 1 :(得分:0)

使用readLine()读取您的文件并使用拆分来获取数据的每个字段,例如:

BufferedReader br = new BufferedReader(new FileReader("FileName"));
String line = null;
ArrayList<Person> list = new ArrayList<Person>();

while ((line = br.readLine()) != null) {
    String[] fields = line.split(",");
    list.add(new Person(fields[0], fields[1], Integer.parseInt(fields[2])));
 } 

然后,您可以将数据保存在需要自定义类的ArrayList中,例如Person,用于存储人员的信息,并在您执行排序逻辑的位置Comparable

如果您需要按人名对数据进行分组,则可以考虑使用Hashtable,其中键是人名,值为ArrayList

您可以为数据定义一个类,例如

class Person implements Comparable<Person> {
    private String name;
    private String company;
    private int experience;

    public Person(String name, String company, int experience) {

        this.name = name;
        this.company = company;
        this.experience = experience;
    }

    public int getExperience() {
        return experience;
    }

    @Override
    public int compareTo(Person person) {
        return new Integer(experience).compareTo(person.getExperience());
    }
}

要对列表进行排序,只需致电Collections.sort(list);;但是此列表将包含所有数据,因此修改代码以按员工姓名对数据进行分组,并为每个员工提供一个列表

答案 2 :(得分:0)

出于您的目的,听起来您确实希望某个对象代表具有一定经验的人。由于您的输入源具有非规范化的数据,因此最简单的方法是在解析文件时填充Map<String,Person>

scanner.useDelimiter(",|\\n");
while (scanner.hasNext()) {
    String line = scanner.next();
    String[] fields = line.split(",");

    String name = fields[0];
    Person person = map.get(name);
    if (person == null) {
        person = new Person(name);
        map.put(name, person);
    }
    person.addJob(fields[1], Integer.parseInt(fields[2]));
}

List<Person> people = new ArrayList<Person>(map.values());

在此过程之后,您将最终得到一个人员列表,没有特别的顺序。对于每个人,由于您希望按照经验对其工作进行排序,因此您需要以保持其有序的方式实施Person.addJob。一个SortedSet是一个非常好的方法,但是你不能插入重复项,因为你想按经验排序,而且一个人可能已经完成了两个工作所需的时间相同使用替代方法。有几种方法可以做到这一点,但是如果不对数据做出假设,我建议保留List Jobclass Person { private final List<Job> jobs = new LinkedList<Job>(); // Constructor, etc... public void addJob(String companyName, int yearsOfExperience) { Job newJob = new Job(companyName, yearsOfExperience); int insertionIndex = Collections.binarySearch(jobs, newJob); if (insertionIndex < 0) { insertionIndex = (-(insertionIndex) - 1); } jobs.add(insertionIndex, newJob); } } 个对象:

Job

最后,Comparable<Job>应该实现class Job implements Comparable<Job> { private final String companyName; private final int yearsOfExperience; // Constructor, etc... public int compareTo(Job otherJob) { return Integer.compare(yearsOfExperience,otherJob.yearsOfExperience); } } ,以便您可以查找:

Person.addJob

List中的那一点诡计将使{{1}}始终按作业的'natural order'排序。 (见Collections.binarySearch)。