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

时间:2021-08-02 07:45:31

I have a comma separated file that contains Employee name,company,years.

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

An employee may be affiliated to multiple companies.

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

For eg,

例如,

John,Google,2
John,Microsoft,1
James,Tesla,1
James,Apple,5

John,Google,2 John,Microsoft,1 James,Tesla,1 James,Apple,5

I have retrieved the information using the java scanner

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

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

I am new to Java and I am trying to insert the above in a sorted order (using experience as sorting criteria) using an array of linked lists or array of array. So

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

employee -> Company1 -> Company2.... (ordered by employee experience)

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

So in the above example, it would be:

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

John->Microsoft->google
James->Tesla->Apple

约翰 - >微软 - >谷歌詹姆斯 - >特斯拉 - >苹果

Can someone point me to the right direction?

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

NOTE: If the experience is same, it doesnt matter which company comes first.

注意:如果经验相同,那么哪个公司是第一位的并不重要。

3 个解决方案

#1


1  

Use this class for Person

将此类用于Person

public class Person {

公共类人员{

@Getter @Setter
private String name;

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

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

}

}

Using the experience as key in a TreeMap will automatically sort the companies for a Person in ascending order.

使用体验作为TreeMap中的键将自动按升序对公司进行排序。

Your main class shoud look like this

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

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();

        }
    }
}

I've tested it and looks pretty, pretty good to me.

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

By the way, the @Getter and @Setter annotations are from the Lombok project. You can either use it or create your own getters/setters.

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

#2


0  

read your file with readLine() and use split to get each field of your data, e.g.:

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

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])));
 } 

You can then save your data in ArrayList that takes a custom class e.g. Person that stores the person's information and implements Comparable where you do the sorting logic.

然后,您可以将数据保存在ArrayList中,该ArrayList采用自定义类,例如存储人员信息并在您执行排序逻辑时实现Comparable的人员。

If you need to group your data by the person name, you might consider having a Hashtable where the key is the person name and the value is ArrayList of experience.

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

You can define a class for your data, e.g.

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

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());
    }
}

The to sort your list just call Collections.sort(list);; however this list will contain all the data so modify the code to group the data by the employee name and have a list per each employee

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

#3


0  

For your purposes, it sounds like you really want an object to represent a Person, who has some amount of Experience. Since your input source has the data denormalized, easiest way to do that is to populate a Map<String,Person> as you parse your file:

出于您的目的,听起来您真的希望一个对象代表具有一定经验的人。由于您的输入源具有非规范化的数据,因此最简单的方法是在解析文件时填充Map ,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());

After this process, you'll end up with a List of People, in no particular order. For each Person, since you want to keep their job's in order sorted by experience, you'd need to implement Person.addJob in such a way as to keep it ordered. A SortedSet is a really nice way to do this, but you can't insert duplicates, and since you want to sort by experience, and a person could've been at two jobs the same amount of time you need to use an alternate approach. There's several ways to do this, but without making assumptions about your data I'd suggest keeping a sorted List of Job objects:

在此过程之后,您将最终得到一个人员列表,没有特别的顺序。对于每个人,由于您希望按照经验对其工作进行排序,因此您需要以保持其有序的方式实现Person.addJob。 SortedSet是一个非常好的方法,但你不能插入重复项,因为你想按经验排序,而且一个人可能在同一时间内完成两个工作需要使用替代方法。有几种方法可以做到这一点,但是如果不对数据做出假设,我建议保留一个排序的Job对象列表:

class 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);
    }
}

and finally, a Job should implement Comparable<Job>, so that you can look it up:

最后,Job应该实现Comparable ,以便您可以查找它:

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);
    }
}

That bit of trickery in Person.addJob will keep the List always sorted by the 'natural order' of Job. (see Collections.binarySearch).

Person.addJob中的那些技巧将使List始终按Job的“自然顺序”排序。 (参见Collections.binarySearch)。

#1


1  

Use this class for Person

将此类用于Person

public class Person {

公共类人员{

@Getter @Setter
private String name;

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

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

}

}

Using the experience as key in a TreeMap will automatically sort the companies for a Person in ascending order.

使用体验作为TreeMap中的键将自动按升序对公司进行排序。

Your main class shoud look like this

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

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();

        }
    }
}

I've tested it and looks pretty, pretty good to me.

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

By the way, the @Getter and @Setter annotations are from the Lombok project. You can either use it or create your own getters/setters.

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

#2


0  

read your file with readLine() and use split to get each field of your data, e.g.:

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

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])));
 } 

You can then save your data in ArrayList that takes a custom class e.g. Person that stores the person's information and implements Comparable where you do the sorting logic.

然后,您可以将数据保存在ArrayList中,该ArrayList采用自定义类,例如存储人员信息并在您执行排序逻辑时实现Comparable的人员。

If you need to group your data by the person name, you might consider having a Hashtable where the key is the person name and the value is ArrayList of experience.

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

You can define a class for your data, e.g.

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

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());
    }
}

The to sort your list just call Collections.sort(list);; however this list will contain all the data so modify the code to group the data by the employee name and have a list per each employee

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

#3


0  

For your purposes, it sounds like you really want an object to represent a Person, who has some amount of Experience. Since your input source has the data denormalized, easiest way to do that is to populate a Map<String,Person> as you parse your file:

出于您的目的,听起来您真的希望一个对象代表具有一定经验的人。由于您的输入源具有非规范化的数据,因此最简单的方法是在解析文件时填充Map ,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());

After this process, you'll end up with a List of People, in no particular order. For each Person, since you want to keep their job's in order sorted by experience, you'd need to implement Person.addJob in such a way as to keep it ordered. A SortedSet is a really nice way to do this, but you can't insert duplicates, and since you want to sort by experience, and a person could've been at two jobs the same amount of time you need to use an alternate approach. There's several ways to do this, but without making assumptions about your data I'd suggest keeping a sorted List of Job objects:

在此过程之后,您将最终得到一个人员列表,没有特别的顺序。对于每个人,由于您希望按照经验对其工作进行排序,因此您需要以保持其有序的方式实现Person.addJob。 SortedSet是一个非常好的方法,但你不能插入重复项,因为你想按经验排序,而且一个人可能在同一时间内完成两个工作需要使用替代方法。有几种方法可以做到这一点,但是如果不对数据做出假设,我建议保留一个排序的Job对象列表:

class 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);
    }
}

and finally, a Job should implement Comparable<Job>, so that you can look it up:

最后,Job应该实现Comparable ,以便您可以查找它:

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);
    }
}

That bit of trickery in Person.addJob will keep the List always sorted by the 'natural order' of Job. (see Collections.binarySearch).

Person.addJob中的那些技巧将使List始终按Job的“自然顺序”排序。 (参见Collections.binarySearch)。