Java 按特定字符串值对字符串数组排序
我有一个项目,其主要功能是将.txt文件读入字符串数组,并按每行中的特定字符串值对其进行排序。我的.txt文件是一份员工名单,上面有他们的姓名、工资和经验。下面是我的示例列表: 姓名:托马斯·格林|工资总额:10000 |工作经验:30个月 姓名:Anna Lang |工资总额:6000 |工作经验:12个月 姓名:Micheal Holse |工资总额:8000 |工作经验:27个月 现在我要做的是,在使用扫描器将列表更改为数组后,通过名字、薪水值或经验值对列表进行排序。我读过关于Comparator的文章,但找不到正确的例子。正如您所看到的,这个程序要做的是跳过Name:value并按名字的字母顺序对其排序。或者跳过其他字符串并按最低薪资值对列表进行排序。经验也是一样,它应该按月数从最低到最高排序 以下是到目前为止我能做的:Java 按特定字符串值对字符串数组排序,java,arrays,string,sorting,collections,Java,Arrays,String,Sorting,Collections,我有一个项目,其主要功能是将.txt文件读入字符串数组,并按每行中的特定字符串值对其进行排序。我的.txt文件是一份员工名单,上面有他们的姓名、工资和经验。下面是我的示例列表: 姓名:托马斯·格林|工资总额:10000 |工作经验:30个月 姓名:Anna Lang |工资总额:6000 |工作经验:12个月 姓名:Micheal Holse |工资总额:8000 |工作经验:27个月 现在我要做的是,在使用扫描器将列表更改为数组后,通过名字、薪水值或经验值对列表进行排序。我读过关于Compar
import java.io.File;
import java.io.IOException;
import java.util.*;
public class SortList {
public static int loadInt() {
Scanner s = new Scanner(System.in);
if(!s.hasNextInt()) {
s.next();
s.nextLine();
return loadInt();
}
return s.nextInt();
}
public static void main (String[] args) throws IOException{
//show the list
String token1 = "";
Scanner inFile1 = new Scanner (new File ("list.txt")).useDelimiter(",\\s*");
List<String> temps = new ArrayList<String>();
while(inFile1.hasNext()) {
token1 = inFile1.next();
temps.add(token1);
}
inFile1.close();
String[] tempsArray = temps.toArray(new String[0]);
for(String s : tempsArray) {
System.out.println(s);
}
//Sort the list
System.out.println("How do you want to sort?" + "\n" + "1. By name" + "\n" + "2. By salary" + "\n" + "3. By experience");
int b;
b = loadInt();
if (b == 1){
ArrayList<String> namesList = new ArrayList<>();
for(int i = 0; i<tempsArray.length; i++){
namesList.add(tempsArray[i]);
}
Collections.sort(namesList, (name1, name5) -> name1.split(" ")[1].compareTo(name5.split(" ")[1]));
for(String name : namesList){
System.out.println(name);
}
}
if (b == 2){
ArrayList<String> salaryList = new ArrayList<>();
for(int i = 0; i<tempsArray.length; i++){
salaryList.add(tempsArray[i]);
}
Collections.sort(salaryList, (salary1, salary2) -> salary1.split(" ")[10].compareTo(salary2.split(" ")[10]));
for(String salary : salaryList){
System.out.println(salary);
}
}
if (b == 3){
ArrayList<String> experienceList = new ArrayList<>();
for(int i = 0; i<tempsArray.length; i++){
experienceList.add(tempsArray[i]);
}
Collections.sort(experienceList, (experience1, experience2) -> experience1.split(" ")[14].compareTo(experience2.split(" ")[14]));
for(String experience : experienceList){
System.out.println(experience);
}
}
}
}
目前,当我输入整数值时,我的代码不会对列表进行排序。我这样做对吗?我通过internet找到了一个收集示例,但它对我不起作用。正确的做法是使用firstName、lastName、salary和experience字段定义一个Employee对象。然后,您可以定义多个支持不同排序选项的比较器实例。然后您可以创建一个列表和调用,它将根据比较器定义的顺序对元素进行排序 该类可能如下所示:
public class Employee {
private final String firstName;
private final String lastName;
private final int salary;
private final int experience;
// constructor, getters
}
public class FirstNameComparator implements Comparator<Employee> {
@Override
public int compare(Employee e1, Employee e2) {
return e1.getFirstName().compareTo(e2.getFirstName());
}
}
您的比较器可能如下所示:
public class Employee {
private final String firstName;
private final String lastName;
private final int salary;
private final int experience;
// constructor, getters
}
public class FirstNameComparator implements Comparator<Employee> {
@Override
public int compare(Employee e1, Employee e2) {
return e1.getFirstName().compareTo(e2.getFirstName());
}
}
或者在Java8中,您可以使用方法引用,只需将Comparator.comparingEmployee::getFirstName传递给Collections.sort的Comparator参数
然后,只需读取文件并从每行中提取字段,然后从每行中构造一个雇员。如果您对文本文件中的数据不确定,本网站上会有许多问题讨论如何解析这些数据。正确的做法是使用firstName、lastName、salary和experience字段定义员工对象。然后,您可以定义多个支持不同排序选项的比较器实例。然后您可以创建一个列表和调用,它将根据比较器定义的顺序对元素进行排序 该类可能如下所示:
public class Employee {
private final String firstName;
private final String lastName;
private final int salary;
private final int experience;
// constructor, getters
}
public class FirstNameComparator implements Comparator<Employee> {
@Override
public int compare(Employee e1, Employee e2) {
return e1.getFirstName().compareTo(e2.getFirstName());
}
}
您的比较器可能如下所示:
public class Employee {
private final String firstName;
private final String lastName;
private final int salary;
private final int experience;
// constructor, getters
}
public class FirstNameComparator implements Comparator<Employee> {
@Override
public int compare(Employee e1, Employee e2) {
return e1.getFirstName().compareTo(e2.getFirstName());
}
}
或者在Java8中,您可以使用方法引用,只需将Comparator.comparingEmployee::getFirstName传递给Collections.sort的Comparator参数
然后,只需读取文件并从每行中提取字段,然后从每行中构造一个雇员。如果您对文本文件中的数据不确定,本网站上会有很多问题讨论解析文本文件中的数据。算法的问题是,当您从文件中读取数据时,Scanner对象会立即读取所有内容,而ArrayList temps只加载了1个元素。更改令牌1=inFile1.next;token1=infie1.nextLine;,其他一切正常。算法的问题是,当您从文件中读取时,Scanner对象会立即读取所有内容,而ArrayList temps只加载了1个元素。更改令牌1=inFile1.next;token1=infie1.nextLine;,其他一切正常。进一步强化了dimo414的建议。如上所述,您创建了一个类,其中包含员工的相关部分 该类可以有一个类似
public Employee(String firstName, String lastName, int salary, int experienceInMonths)
然后你会创造出像这样的员工
List<Employee> employees = new ArrayList<>();
employees.add( new Employee ("Bilbo", "Beutlin", 5, 10) );
那么,你知道的是:
您可以编写代码逐行读取该文件
您创建了一个助手方法,该方法接受一条这样的线。。。并为其返回一个Employee对象
比如:
在该方法中,您只需解析该字符串并提取相关信息。根据您的格式,您可以执行以下操作:
使用\|。。。这应该把你的行切成三个子串
第一个子串是Name:thomasgreen。在这里,您将使用String.substring获取以下内容:;给你托马斯·格林。然后你可以假设最后一个空格后面的任何东西都是姓氏;而之前的任何东西都是第一个名字
然后使用Integer.valueOf等方法对输入部分执行类似操作,以将字符串数字转换为int
最后,调用“returnnewEmployeeFirstNameParsedFromInput,…”。。。。
事情是:你必须分开考虑。一个问题是使用Employee类对数据建模;另一个问题是解析字符串以检索构成员工的元素。只有当所有这些都很好地工作时,您才开始研究Collections.sort并编写自己的Comparator类。进一步增强了dimo414的建议。如上所述,您创建了一个类,其中包含员工的相关部分 那个班可以有一个c 结构式
public Employee(String firstName, String lastName, int salary, int experienceInMonths)
然后你会创造出像这样的员工
List<Employee> employees = new ArrayList<>();
employees.add( new Employee ("Bilbo", "Beutlin", 5, 10) );
那么,你知道的是:
您可以编写代码逐行读取该文件
您创建了一个助手方法,该方法接受一条这样的线。。。并为其返回一个Employee对象
比如:
在该方法中,您只需解析该字符串并提取相关信息。根据您的格式,您可以执行以下操作:
使用\|。。。这应该把你的行切成三个子串
第一个子串是Name:thomasgreen。在这里,您将使用String.substring获取以下内容:;给你托马斯·格林。然后你可以假设最后一个空格后面的任何东西都是姓氏;而之前的任何东西都是第一个名字
然后使用Integer.valueOf等方法对输入部分执行类似操作,以将字符串数字转换为int
最后,调用“returnnewEmployeeFirstNameParsedFromInput,…”。。。。
事情是:你必须分开考虑。一个问题是使用Employee类对数据建模;另一个问题是解析字符串以检索构成员工的元素。只有当所有这些都很好地工作时,您才开始研究Collections.sort并编写自己的Comparator类。这里真正的问题是,在处理各种排序操作之前,您需要一个合理的对象模型。从这个意义上说,迪莫的答案绝对是你必须要了解的。谢谢你的解释。但如果我创建名为Employee的对象,我将如何从txt文件加载列表?我是Java初学者,因此我无法想象如何从txt文件加载对象。哇,我花了一些时间为您写了一个答案。希望这会有所帮助,因为我有一种模糊的感觉,我甚至不会看到太多的赞成票…这里真正的事情是,你需要一个合理的对象模型,然后再做任何关于这些排序的事情。从这个意义上说,迪莫的答案绝对是你必须要了解的。谢谢你的解释。但如果我创建名为Employee的对象,我将如何从txt文件加载列表?我是Java初学者,因此我无法想象如何从txt文件加载对象。哇,我花了一些时间为您写了一个答案。希望这会有所帮助,因为我有一种模糊的感觉,我甚至不会看到太多的赞成票…+1,因为我提到了带有Comparator.comparating的Java8解决方案。大多数人甚至不知道从哪里开始实现Comparator,所以一个现成的解决方案是非常有用的。感谢您的解释,但是我应该用构造函数创建一个文件,还是在我的程序中实现这一部分。所以最好的选择是将数据解析成可比较的字段?恐怕我不理解你的问题。类有构造函数,而不是文件;您可以在任何地方定义比较器—单独的文件、SortList中的嵌套类,甚至是匿名类/lambda。关键点是将解析步骤与排序步骤分开。将文本文件解析为结构化对象,然后对这些对象进行排序。@ifly6是的,Java 8对Comparator进行了一些重大改进。在Java-8之前的版本中,Guava的和类也有类似的用途。+1用于使用Comparator.Comparating提及Java 8解决方案。大多数人甚至不知道从哪里开始实现Comparator,所以一个现成的解决方案是非常有用的。感谢您的解释,但是我应该用构造函数创建一个文件,还是在我的程序中实现这一部分。所以最好的选择是将数据解析成可比较的字段?恐怕我不理解你的问题。类有构造函数,而不是文件;您可以在任何地方定义比较器—单独的文件、SortList中的嵌套类,甚至是匿名类/lambda。关键点是将解析步骤与排序步骤分开。将文本文件解析为结构化对象,然后对这些对象进行排序。@ifly6是的,Java 8对Comparator进行了一些重大改进。在Java-8土地GuAVA和类中有类似的用途。感谢输入,我将在编写Effice类时考虑这种方法。欢迎您。请记住我的回答,一旦你达到15个代表和投票特权:谢谢你的投入,我会考虑这个方法时写的雇员类。当您达到15个代表和投票特权时,请记住我的回答:-