使用Java Stream API根据缩写对用户进行排序。如果缩写重复,请根据用户的年龄进行排序。他们俩都以降序排序

发布于 2025-02-08 13:01:56 字数 1239 浏览 2 评论 0原文

我正在尝试根据用户的缩写对用户进行排序,当重复缩写时,例如“ Alex Fay”和“ Alba Finn”,我必须根据他们的年龄下降顺序对其进行分类。

这是我当前的代码:

List<SortedUser> sortedUserList = list.stream()
        .sorted((a, b) -> {
             int first = a.getName().charAt(0) + a.getLastName().charAt(0);
             int second = b.getName().charAt(0) + b.getLastName().charAt(0);
             if(first > second) {
                  return -1;
             } if(first < second) {
                   return 1;
             }

             return b.getAge() - a.getAge();
           }).collect(Collectors.toList()); 

此代码的问题是,当我具有缩写“ ar”和“ en”时,它们的总和相同(147) - 因此, first = =第二 ,它们以不正确的顺序出现。 我还试图将初始名字和姓氏初始名称分开比较,但我仍然无法正常工作。

为了按照我想要的方式对它们进行分类,我该更改什么?

样本输入:

(name=Alexandre, lastName=Wuckert, age=66),
(name=Allan, lastName=Wehner, age=84),
(name=Bradley, lastName=Thompson, age=78),
(name=Bernice, lastName=Schoen, age=63)

样本输出:

(name=Bradley, lastName=Thompson, age=78),
(name=Bernice, lastName=Schoen, age=63),
(name=Allan, lastName=Wehner, age=84),
(name=Alexandre, lastName=Wuckert, age=66)

I am trying to sort users based on their initials, and when initials are repeated, say 'Alex Fay' and 'Alba Finn', I have to sort them based on their age in descending order.

This is my current code:

List<SortedUser> sortedUserList = list.stream()
        .sorted((a, b) -> {
             int first = a.getName().charAt(0) + a.getLastName().charAt(0);
             int second = b.getName().charAt(0) + b.getLastName().charAt(0);
             if(first > second) {
                  return -1;
             } if(first < second) {
                   return 1;
             }

             return b.getAge() - a.getAge();
           }).collect(Collectors.toList()); 

The problem with this code is that when I have initials 'AR' and 'EN', their sums are the same (147) - therefore first == second, and they appear one after the other in incorrect order.
I also tried to compare the first name initial and the last name initial separately, but I still couldn't get it to work.

What can I change in order to sort them the way I want it?

Sample input:

(name=Alexandre, lastName=Wuckert, age=66),
(name=Allan, lastName=Wehner, age=84),
(name=Bradley, lastName=Thompson, age=78),
(name=Bernice, lastName=Schoen, age=63)

Sample output:

(name=Bradley, lastName=Thompson, age=78),
(name=Bernice, lastName=Schoen, age=63),
(name=Allan, lastName=Wehner, age=84),
(name=Alexandre, lastName=Wuckert, age=66)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

几味少女 2025-02-15 13:01:56

添加字符进行排序是不可靠的,因为许多对可以总和到相同的值。因此,您应该构建一串缩写而不是添加它们。然后在您的排序方法中使用以下内容。

String first = a.getName().charAt(0) + "" + a.getLastName().charAt(0);
String second = b.getName().charAt(0) +"" + b.getLastName().charAt(0);
int result = first.compareTo(second);
    
return result > 0 ? -1 : result < 0 ? 1 : b.getAge-a.getAge();

以上将根据缩写以降序排序。如果结果== 0,则将使用年龄(如您以前一样)。

注意:您也可以做second.compareto(first),然后交换1和-1或交换不平等标志< /代码>。这对您来说更有意义。

这是您考虑的其他一些选择。我使用记录保存用户数据。

record User(String getName, String getLastName, int getAge) {
}

List<User> list =
        new ArrayList<>(List.of(new User("Alexandre", "Wuckert", 66),
                new User("Allan", "Wehner", 84),
                new User("Bradley", "Thompson", 78),
                new User("Bernice", "Schoen", 63)));
  • 流动用户列表。
  • 您可以创建一个字符串比较器,然后将其应用于sort方法,
Comparator<User> compUsers = Comparator
        .comparing((User u) -> u.getName().charAt(0) + ""
                + u.getLastName().charAt(0))
        .thenComparing(User::getAge).reversed();
  • 请首先比较缩写
  • 如果缩写相等,
  • ,然后比较用户的年龄。反向()反向是以前的比较器,从上升(默认)变为降序。

List<User> sortedUsers = list.stream().sorted(compUsers).toList();

sortedUsers.forEach(System.out::println);

打印

User[getName=Bradley, getLastName=Thompson, getAge=78]
User[getName=Bernice, getLastName=Schoen, getAge=63]
User[getName=Allan, getLastName=Wehner, getAge=84]
User[getName=Alexandre, getLastName=Wuckert, getAge=66]

注意,您也可以将列表对位进行排序,而不使用stream,只要列表可变。这里使用了先前定义的比较器

list.sort(compUsers);

注意:也可以将比较代码直接放入sort方法中。但是,将其分开定义可以重复使用,并且可以使溪流构造不那么混乱。

Adding characters to sort on is unreliable since many pairs can sum to the same value. So you should build a String of initials rather than add them. Then use the following in your sort method.

String first = a.getName().charAt(0) + "" + a.getLastName().charAt(0);
String second = b.getName().charAt(0) +"" + b.getLastName().charAt(0);
int result = first.compareTo(second);
    
return result > 0 ? -1 : result < 0 ? 1 : b.getAge-a.getAge();

The above will sort in descending order based on the initials. If result == 0 then the ages will be used (as you did before).

Note: you could also do second.compareTo(first) and then either swap 1 and -1 or swap the inequality signs. Which ever makes more sense to you.

Here are some other alternatives for your consideration. I used a record to hold the User data.

record User(String getName, String getLastName, int getAge) {
}

List<User> list =
        new ArrayList<>(List.of(new User("Alexandre", "Wuckert", 66),
                new User("Allan", "Wehner", 84),
                new User("Bradley", "Thompson", 78),
                new User("Bernice", "Schoen", 63)));
  • stream the list of users.
  • You can create a String comparator and then apply it to the sort method
Comparator<User> compUsers = Comparator
        .comparing((User u) -> u.getName().charAt(0) + ""
                + u.getLastName().charAt(0))
        .thenComparing(User::getAge).reversed();
  • first compare the initials
  • if the initials are equal, then compare on the user's age.
  • reversed() reverses are previous comparators to change from ascending (default) to descending.

List<User> sortedUsers = list.stream().sorted(compUsers).toList();

sortedUsers.forEach(System.out::println);

prints

User[getName=Bradley, getLastName=Thompson, getAge=78]
User[getName=Bernice, getLastName=Schoen, getAge=63]
User[getName=Allan, getLastName=Wehner, getAge=84]
User[getName=Alexandre, getLastName=Wuckert, getAge=66]

Note that you could also just sort the list in place and not use streams as long as the list is mutable. Here the previously defined Comparator is used.

list.sort(compUsers);

Note: It is also possible to put the Comparator code directly into the sort method. But defining it separately lends itself to reuse and can make the stream construct less cluttered.

在你怀里撒娇 2025-02-15 13:01:56

要使代码更可读取且易于错误,请使用比较器接口的Java 8静态方法,而不是将条件链放入lambda表达式中。

这是实现A 比较器的另一种方法,它将根据名字的第一个字母进行比较用户,然后用姓氏的名字来比较订单:

Comparator<SortedUser> byFirstLettersAndAgeReversed =
    Comparator.comparingInt((SortedUser user) -> user.getFirstName().charAt(0))
        .thenComparingInt(user -> user.getLastName().charAt(0))
        .thenComparingInt(SortedUser::getAge).reversed();


 List<SortedUser> sortedUserList = list.stream()
    .sorted(byFirstLettersAndAgeReversed)
    .collect(Collectors.toList());

您可以将几个比较器定义为public static在用户类中的字段,并在需要以特定方式对这些对象进行排序或比较这些对象时重复使用它们。

To make the code more readable and less error-prone, use Java 8 static methods of the Comparator interface instead of placing a chain of conditions into a lambda expression.

Here's another way of implementing a comparator that will compare users based on the first letter of the first name, then by the first letter of the last name and finally by age in descending order:

Comparator<SortedUser> byFirstLettersAndAgeReversed =
    Comparator.comparingInt((SortedUser user) -> user.getFirstName().charAt(0))
        .thenComparingInt(user -> user.getLastName().charAt(0))
        .thenComparingInt(SortedUser::getAge).reversed();


 List<SortedUser> sortedUserList = list.stream()
    .sorted(byFirstLettersAndAgeReversed)
    .collect(Collectors.toList());

You can define a couple of comparators as public static fields inside the user class and reuse them, when you need to sort or compare these objects in a specific way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文