按字母顺序(不区分大小写)对数组列表进行排序

131

我有一个字符串数组列表names,其中包含人名。我想按字母顺序对数组列表进行排序。

ArrayList<String> names = new ArrayList<String>();
names.add("seetha");
names.add("sudhin");
names.add("Swetha");
names.add("Neethu");
names.add("ananya");
names.add("Athira");
names.add("bala");
names.add("Tony");
names.add("Karthika");
names.add("Nithin");
names.add("Vinod");
names.add("jeena");
Collections.sort(names);
for(int i=0; i<names.size(); i++)
    System.out.println(names.get(i));

我试图按照上面的方法对列表进行排序。但是它显示的排序后的数组如下:

Athira
Karthika
..
..
ananya
bala
...

但我不想使它大小写敏感。我希望结果是:

ananya
Athira
bala
10个回答

354

自定义比较器应该有所帮助。

Collections.sort(list, new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        return s1.compareToIgnoreCase(s2);
    }
});

如果您使用的是Java 8:

list.sort(String::compareToIgnoreCase);

1
你能告诉我什么是字符串s1和s2吗?如果比较函数返回整数值,如何查看结果? - andro-girl
@denis.solonenko,感谢您的回答。我已经尝试了您提供的解决方案来对A1到A10的ArrayList进行排序,但是A10没有正确地排序。不知何故,A10排在了A1之后。基本上,它的排序方式是A1,A10,A2,A3等。为什么会发生这种情况,我该如何正确地对列表进行排序? - Dante
2
@Dante,如果你查看String.CASE_INSENSITIVE_ORDER的实现,你会发现A1被认为比A10“小”,仅仅是因为长度更短。它没有支持“自然排序”,你可能想看一下https://dev59.com/snM_5IYBdhLWcg3wt1g0。 - denis.solonenko
我正在使用这段代码,它运行良好。我需要从ArrayList中获取两个日期(开始和结束)之间的数据。我该如何更改这段代码? - sasikumar
@Dante 或许我来晚了,但其他人可以看到并理解这个问题。问题在于为什么 A10 在 A1 和 A2 之间。因为使用字符串进行排序时,会逐个查找单词,例如 AA、AB、BA、BB。所以它将首先对第一个单词进行排序,然后对第二个单词进行排序。因此,A10 和 A2 将首先按字母 A 排序,然后将数字 1 排序与数字 2 排序。长度不受影响。因此,要使其排序,请在 2 前面添加 0,例如 A01、A02、...、A10。 - Akirayjin
显示剩余4条评论

206

最简单的方法是:

Collections.sort(list, String.CASE_INSENSITIVE_ORDER);

@djunod,感谢您的回答。我也尝试了您提供的ArrayList解决方案,从A1到A10,但是A10没有像denis.solenenko的解决方案一样正确排序。不知何故,A10排在了A1之后。基本上,它的排序方式是A1,A10,A2,A3等。为什么会发生这种情况,我该如何正确地对列表进行排序? - Dante
2
@dante,那是普通的字符串排序。如果你想让A2在A10之前出现,你需要将其更改为A02等。 - djunod
1
加1。在Android中也可以工作。谢谢和祝贺。 - statosdotcom
@djunod 非常感谢您 :) - Kumar
2
StackOverflow 应该为我提供像这样保存答案/代码片段的选项。 - HB.

30

试试这段代码

Collections.sort(yourarraylist, new SortBasedOnName());



import java.util.Comparator;
import com.RealHelp.objects.FBFriends_Obj;
import com.RealHelp.ui.importFBContacts;

public class SortBasedOnName implements Comparator
{
public int compare(Object o1, Object o2) 
{

    FBFriends_Obj dd1 = (FBFriends_Obj)o1;// where FBFriends_Obj is your object class
    FBFriends_Obj dd2 = (FBFriends_Obj)o2;
    return dd1.uname.compareToIgnoreCase(dd2.uname);//where uname is field name
}

}

3
很棒的答案!我认为如果你将“implements Comparator”改为“implements Comparator<FBFriends_Obj>”,并将compare中的Object类型更改为FBFriends_Obj,那么你就不需要dd1和dd2了,可以直接在return语句中使用o1和o2。 - FrinkTheBrave

16

基于上述答案,我成功地进行了自定义类对象的比较,如下所示:

ArrayList<Item> itemList = new ArrayList<>();
...
Collections.sort(itemList, new Comparator<Item>() {
            @Override
            public int compare(Item item, Item t1) {
                String s1 = item.getTitle();
                String s2 = t1.getTitle();
                return s1.compareToIgnoreCase(s2);
            }

        });

6
很遗憾,到目前为止所有的答案都没有考虑在排序时 "a" 不能等同于 "A"
String[] array = {"b", "A", "C", "B", "a"};

// Approach 1
Arrays.sort(array);
// array is [A, B, C, a, b]

// Approach 2
Arrays.sort(array, String.CASE_INSENSITIVE_ORDER);
// array is [A, a, b, B, C]

// Approach 3
Arrays.sort(array, java.text.Collator.getInstance());
// array is [a, A, b, B, C]

在方法1中,所有小写字母都被认为比任何大写字母要大。

方法2更糟糕,因为CASE_INSENSITIVE_ORDER将“a”和“A”视为相等(比较结果为0)。这使得排序是不确定的。

方法3(使用java.text.Collator)是我认为唯一正确的方法,因为它认为“a”和“A”不相等,但根据当前(或任何其他所需的)Locale将它们放在正确的顺序。


4

Java 8开始,您可以使用Stream

List<String> sorted = Arrays.asList(
                          names.stream().sorted(
                              (s1, s2) -> s1.compareToIgnoreCase(s2)
                          ).toArray(String[]::new)
                      );

它从那个ArrayList获取一个流,然后对其进行排序(忽略大小写)。之后,该流被转换为一个数组,再转换为ArrayList。
如果您使用以下方式打印结果:
System.out.println(sorted);

您将获得以下输出:

[ananya, Athira, bala, jeena, Karthika, Neethu, Nithin, seetha, sudhin, Swetha, Tony, Vinod]

4

您需要使用自定义比较器,该比较器将使用 compareToIgnoreCase,而不是 compareTo。


我尝试了这个链接,但是我找不到解决方案。你能否请解释一下? - andro-girl

0

Kotlin。按字符串字段排序对象,不区分大小写。

items?.sortedWith { o1, o2 ->
            o1.name.compareTo(o2.name, true)
        }

0
def  lst = ["A2", "A1", "k22", "A6", "a3", "a5", "A4", "A7"]; 

println lst.sort { a, b -> a.compareToIgnoreCase b }

这应该能够进行不区分大小写的排序,但我不确定如何处理包含字母数字的字符串列表。


-1

KOTLIN 开发者

对于 自定义列表,如果您想要基于一个字符串进行排序,则可以使用以下代码:

phoneContactArrayList.sortWith(Comparator { item, t1 ->
        val s1: String = item.phoneContactUserName
        val s2: String = t1.phoneContactUserName
        s1.compareTo(s2, ignoreCase = true)
    })

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接