gpt4 book ai didi

java - 在 java 中按列标题对二维列表进行排序

转载 作者:行者123 更新时间:2023-12-04 15:10:08 24 4
gpt4 key购买 nike

我正在做一个可以读写 CSV 的简单数据框,并且包括按列排序的排序功能。如何通过输入列标题对正确的列进行排序,并从排序中排除列标题行?

这是 CSV 文件的示例数据:

Name,Age,Salary
Lim,20,2000
Tan,20,3000
Mah,19,2500
Roger,10,4000

我已经声明了我的 2D 列表,数据将如下所示:

List<List<String>> COLUMNDATA = new ArrayList();
COLUMNDATA = [[Name, Age, Salary], [Lim, 20, 2000], [Tan, 20, 3000], [Mah, 19, 2500], [Roger, 10, 4000]]

我想通过传入列标题对正确的列进行排序,而列标题行不包括在排序中。例如:

COLUMNDATA.sort(“Age”)

所以会变成这样:

Name,Age,Salary
Roger,10,4000
Mah,19,2500
Lim,20,2000
Tan,20,3000

我已经使用了 ComparatorCollections.sort,但现在卡住了。如何实现我想要的功能?

final Comparator<List<String>> comparator = new Comparator<List<String>>() {
@Override
public int compare(List<String> object1, List<String> object2) {
return object1.get(1).compareTo(object2.get(1));
}
};

Collections.sort(COLUMNDATA, comparator);
for (List<String> list : COLUMNDATA) {
System.out.println(list);
}

最佳答案

这里是如何按照你的要求去做的。定义比较器后,只需对从列表 1 开始的 sublist 进行排序,跳过标题。由于它是原始列表的 View ,因此它仍然对所需项目进行排序。

先做一个field map,在哪个field排序。如果需要,您可以使这种大小写不敏感。对于这个例子,大小写很重要。

static Map<String, Integer> sortingFields = new HashMap<>();
static {
List<String> columns = List.of("Name", "Age", "Salary");
for (int i = 0; i < columns.size(); i++) {
sortingFields.put(columns.get(i), i);
}
}

创建列表列表。

List<List<String>> data = new ArrayList<>();
data.add(new ArrayList<>(List.of("Name" ,"Age", "Salary")));
data.add(new ArrayList<>(List.of("Lim", "20", "4000")));
data.add(new ArrayList<>(List.of("Tan", "20", "3000")));
data.add(new ArrayList<>(List.of("Mah", "19", "2500")));
data.add(new ArrayList<>(List.of("Roger", "10", "3500")));

现在调用排序和打印

sort("Age", data);
data.forEach(System.out::println);

打印

[Name, Age, Salary]
[Roger, 10, 3500]
[Mah, 19, 2500]
[Lim, 20, 4000]
[Tan, 20, 3000]

这里是排序方法。

public static void sort(String Column, List<List<String>> data) {
// use the column string to select the column number to sort.
Comparator<List<String>> comp =
(a, b) -> a.get(sortingFields.get(column))
.compareTo(b.get(sortingFields.get(column)));

data.subList(1,data.size()).sort(comp);
}


下面是我建议您组织数据和进行排序的方式。

首先创建一个类,如图所示。然后使用数据用类的实例填充列表。然后只需指定要排序的 setter/getter 。您可以根据需要添加任意数量的附加字段及其 getter。

原因是它允许混合类型存储在同一个对象中,并且仍然可以排序。如果您对 String number 进行排序,它将按 lexcally 而不是 numerical 排序。这将是一个问题,除非您转换为整数(要查看此内容,请将 4000 更改为 400 并按上面的薪水排序)。但是如果你想按名称排序,你需要一个不同的比较器,因为将非 int 转换为 int 会抛出异常。这一切都可以在某种程度上得到缓解,但它不像创建一个类那么简单。

只需将方法引用更改为所需的getter,您就可以在任何字段上对List 进行排序。如果没有 getter,并且该字段是公共(public)的(不推荐),您可以使用 lambda。

public class SortingByColumn {

public static void main(String[] args) {

List<Person> data = new ArrayList<>();
data.add(new Person("Lim", 20, 2000));
data.add(new Person("Tan", 20, 3000));
data.add(new Person("Mah", 19, 2500));
data.add(new Person("Roger", 10, 4000));

List<Person> sorted = data.stream()
.sorted(Comparator.comparing(Person::getAge))
.collect(Collectors.toList());
System.out.printf("%10s %10s %10s%n", "Name","Age","Salary");
sorted.forEach(System.out::println);
}

static class Person {
private String name;
private int age;
private int salary;

public Person(String name, int age, int salary) {
this.name = name;
this.age = age;
this.salary = salary;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}

public int getSalary() {
return salary;
}

@Override
public String toString() {
return String.format("%10s %10s %10s", name, age,
salary);
}
}
}

打印

      Name         Age      Salary
Roger 10 4000
Mah 19 2500
Lim 20 2000
Tan 20 3000

关于java - 在 java 中按列标题对二维列表进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65363023/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com