【问题标题】:Sorting an array (Object[]) consisting of integers and strings - Java对由整数和字符串组成的数组 (Object[]) 进行排序 - Java
【发布时间】:2015-03-29 01:29:46
【问题描述】:

我有一个 Object[] 类型的数组,包含整数和字符串(单个字母)。

Object[] myArray = {(String) "U", (String) "U", (int) 2, (String) "X", (int) 4, (String) "U"};

我的问题是,有没有一种简单的方法来对这个数组进行排序,首先是在字符串之前的整数,其次是按数字升序排列的整数和按字母顺序排列的字符串? 我一直在寻找类似于 Arrays.sort 方法的东西,但我认为它不会那么简单。

谢谢

【问题讨论】:

  • 这个没意义,创建char数组或者字符串数组,用Arrays.sort排序即可。
  • 感谢您的回答!请问能详细点吗?我对Java相当陌生,但据我所知,您的建议可能行不通?即在字符串数组中包含整数(如您所建议的那样)不起作用? @libik
  • @user3636636 拥有一系列异构类型通常表明存在设计问题。
  • 为什么要将字符串文字转换为String,将整数文字转换为int?

标签: java arrays sorting


【解决方案1】:

一种方法是提供一个Comparator<Object> 实例并检查对象的类型以确定它们的排序:

Arrays.sort(myArray, new IntStringComparator());

//...

public static class IntStringComparator implements Comparator<Object> {

    @Override
    public int compare(Object o1, Object o2) {
        if (o1 == null) {
            return -1; // o1 is null, should be less than any value 
        }
        if(o2 == null){
            return 1; // o2 is null, should be less than any non-null value
        }
        if (o1 instanceof Integer) {
            if (o2 instanceof Integer) {
                return Integer.compare((int) o1, (int) o2); // Compare by int
            } else {
                return -1; // int < String
            }
        } else {
            if (o2 instanceof String) {
                return ((String) o1).compareTo((String) o2); // Compare by string
            } else {
                return 1; // String > int
            }
        }
    }
}

输出:

[2, 4, U, U, U, X]

【讨论】:

    【解决方案2】:

    在 Java 8 中:

        Object[] myArray = {(String) "U", (String) "U", (int) 2, (String) "X", (int) 4, (String) "U"};
        Stream.of(myArray).filter(x -> !(x instanceof String))
                .sorted().forEach(System.out::print);
        Stream.of(myArray).filter(x -> x instanceof String)
                            .sorted().forEach(System.out::print);
    

    对于大卫华莱士:如果你想保存排序后的数组(在这个例子中我将它保存到 List,但如果你愿意,它可以转换为 .toArray()):

        Object[] myArray = {(String) "U", (String) "U", (int) 2, (String) "X", (int) 4, (String) "U"};
        List<Object> newList = Stream.of(myArray).filter(x -> x instanceof String)
                            .sorted().collect(Collectors.toList());
        Collections.addAll(newList, Stream.of(myArray).filter(x -> !(x instanceof String))
                .sorted().toArray());
    
        for (Object o : newList) {
            System.out.print(o);
        }
    

    OUTPUT(两个代码 sn-ps):

    24UUUX
    

    也就是说,在同一个数组中混合不同类型是一种不好的做法(像你一样使用Object)。不同的类型只有在它们有一个共同的接口时才应该“混合”(或者,如果它们中的一个扩展了另一个)!

    【讨论】:

    • OP 在输出中在 Strings 之前请求了 ints。
    • 感谢您的回答!非常有帮助。鉴于我所做的是不好的做法,您能否建议一个更好的数据结构来保存给定的整数和字符串?谢谢@alfasin
    • @user3636636 好吧.. 重点不是提供不同的数据结构,重点是不同的类型不应该混用!如果有一个共同的含义,应该有一个对象来包装它们并反映这个属性。但是由于我不知道这个练习背后的意图是什么 - 我找不到整数和字符串共享的公共属性。
    • 很好地使用了Streams。具有讽刺意味的是,它们几乎让静态类型在这里显得毫无意义!
    • 这实际上不是对数组进行排序是吗?你永远不会得到一个数组,先是数字,然后是字母,按这个顺序排序。
    【解决方案3】:

    您可以指定用于比较对象的函数,从而使其行为随心所欲。示例见Java - How can I most-efficiently sort an array of SomeClass objects by a String field in those objects?

    【讨论】:

      【解决方案4】:

      我认为最好的方法是创建一个实现 Comparable 接口的通用类。这样您就可以将任何类型存储在 Array 中,并使用 compare 方法来做任何您想做的事情。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-05-30
        • 2015-07-27
        • 2019-08-05
        • 2021-03-21
        • 1970-01-01
        • 1970-01-01
        • 2017-06-07
        • 1970-01-01
        相关资源
        最近更新 更多