简体   繁体   English

对由整数和字符串组成的数组(Object [])进行排序 - Java

[英]Sorting an array (Object[]) consisting of integers and strings - Java

I have and array of type Object[], containing integers and strings (single letters). 我有和Object []类型的数组,包含整数和字符串(单个字母)。

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

What my question is, is there a simple way to sort this array, firstly by ints before strings and secondly by ints in numerical ascending order and string in alphabetical order? 我的问题是,是否有一种简单的方法可以对这个数组进行排序,首先是在字符串之前进行整理,然后按数字升序整数和按字母顺序排列字符串? I was looking for something similar to the Arrays.sort method, but i don't think it will be that simple. 我正在寻找类似于Arrays.sort方法的东西,但我不认为它会那么简单。

Thank you 谢谢

One way would be to provide a Comparator<Object> instance and check the type of the objects to determine their sorting: 一种方法是提供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
            }
        }
    }
}

Outputs: 输出:

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

In Java 8: 在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);

For David Wallace: in case you want to save the sorted array (I save it to List in this example but it can be converted into .toArray() if you want): 对于David Wallace:如果你想保存已排序的数组(在本例中我将它保存到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 (of both code snippets): OUTPUT (两个代码片段):

24UUUX

That said, it's a bad practice to mix different types in the same array (to use Object like you did). 也就是说,在同一个数组中混合使用不同的类型是一种不好的做法(像你一样使用Object )。 Different types should be "mixed" only if they have an interface in common (or, if one of them extends the other )! 只有当它们有一个共同的接口时(或者,如果其中一个扩展另一个),不同类型应该“混合”!

You can specify the function to use to compare objects, and so make it behave however you like. 您可以指定用于比较对象的函数,因此可以根据需要使其运行。 For an example, see Java - How can I most-efficiently sort an array of SomeClass objects by a String field in those objects? 有关示例,请参阅Java - 如何通过这些对象中的String字段最有效地对SomeClass对象数组进行排序?

I think the best way to go is to create a Generic Class which will implement the Comparable interface. 我认为最好的方法是创建一个实现Comparable接口的Generic Class。 Such that you can store any type in a Array and having a compare method to do what ever you want. 这样你就可以在Array中存储任何类型并使用compare方法来做任何你想做的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM