tl;博士
List < String > sorted =
List.of(
"Mark,10,0,34" ,
"Tom,2,7,19" ,
"Billy,2,0,7"
)
.stream()
.sorted( ( String s1 , String s2 ) -> Integer.valueOf( s1.split( "," )[ 3 ] ).compareTo( Integer.valueOf( s2.split( "," )[ 3 ] ) ) )
.toList();
流
你问:
使用 lambda 表达式对对象的 ArrayList(即从 CSV 文件导入的行)进行排序,
换句话说,您希望按以逗号 (,) 分隔的最后一部分对 String 对象列表进行排序。
对于每个字符串,我们需要调用String#split,返回一个部分数组。鉴于您的示例数据,我们预计恰好有四个部分。所以采取最后一部分。 Java 中的数组令人讨厌地使用索引,即从零开始的计数。所以第 4 项是索引 3,语法上是 [3]。
此代码效率不高,因为排序涉及对compareTo 的多次重复调用。对于每个调用,我们都会重新进行拆分。效率不高,但有效。
List < String > inputs =
new ArrayList <>(
List.of(
"Mark,10,0,34" ,
"Tom,2,7,19" ,
"Billy,2,0,7"
)
);
List < String > sorted =
inputs
.stream()
.sorted( ( String s1 , String s2 ) -> Integer.valueOf( s1.split( "," )[ 3 ] ).compareTo( Integer.valueOf( s2.split( "," )[ 3 ] ) ) )
.toList(); // Before Java 16: .collect( Collectors.toList() );
System.out.println( "sorted = " + sorted );
看到这个code run live at IdeOne.com。
排序 = [Billy,2,0,7, Tom,2,7,19, Mark,10,0,34]
记录
您的问题确实没有意义,因为它明确避免使用类。 Java 是一种面向对象的语言。类是它的基础,它的存在理由。
如果您只是因为必需的样板而不愿意定义一个类,我有个好消息要告诉您。 Java 16 带来了新的records 功能。
记录是声明一个类的一种简短方式,该类的主要目的是透明且不可变地传递数据。您只需声明所有类成员字段的类型和名称。编译器隐式创建构造函数、getter、equals & hashCode 和 toString。
所以一个完整的类可以写在一个短行上。
record Person ( String name , int departmentId , int projectId , int employeeId ) {}
根据您的输入数据填充Person 对象的集合。
List < Person > persons = new ArrayList <>( inputs.size() );
for ( String input : inputs )
{
String[] parts = input.split( "," );
Person p = new Person( parts[ 0 ] , Integer.valueOf( parts[ 1 ] ) , Integer.valueOf( parts[ 2 ] ) , Integer.valueOf( parts[ 3 ] ) );
persons.add( p );
}
按最后一个成员字段employeeId对该列表进行排序。
Collections.sort(
persons ,
new Comparator < Person >()
{
@Override
public int compare ( Person p1 , Person p2 )
{
return Integer.compare( p1.employeeId() , p2.employeeId() );
}
}
);
这里是完整的例子。
package work.basil.demo;
import java.util.*;
import java.lang.*;
public class RecordDemo
{
public static void main ( String[] args )
{
List < String > inputs =
new ArrayList <>(
List.of(
"Mark,10,0,34" ,
"Tom,2,7,19" ,
"Billy,2,0,7"
)
);
record Person(String name , int departmentId , int projectId , int employeeId)
{
}
List < Person > persons = new ArrayList <>( inputs.size() );
for ( String input : inputs )
{
String[] parts = input.split( "," );
Person p = new Person( parts[ 0 ] , Integer.valueOf( parts[ 1 ] ) , Integer.valueOf( parts[ 2 ] ) , Integer.valueOf( parts[ 3 ] ) );
persons.add( p );
}
System.out.println( "persons = " + persons );
Collections.sort(
persons ,
new Comparator < Person >()
{
@Override
public int compare ( Person p1 , Person p2 )
{
return Integer.compare( p1.employeeId() , p2.employeeId() );
}
}
);
System.out.println( "persons = " + persons );
}
}
运行时。
persons = [Person[name=Mark, departmentId=10, projectId=0, employeeId=34], Person[name=Tom, departmentId=2, projectId=7, employeeId=19], Person[name=Billy, departmentId=2, projectId=0, employeeId=7]]
persons = [Person[name=Billy, departmentId=2, projectId=0, employeeId=7], Person[name=Tom, departmentId=2, projectId=7, employeeId=19], Person[name=Mark, departmentId=10, projectId=0, employeeId=34]]
在上面的代码中,请注意记录的另一个好处:您可以在本地声明记录,在方法内,以及嵌套在类或单独的类(.java 文件)中。在 Java 团队参与的同时,他们现在也允许本地枚举定义,以及本地接口定义。 Java 16 及更高版本中的所有内容。