RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1593639
Accepted
HeavyRiden
HeavyRiden
Asked:2024-09-12 16:47:23 +0000 UTC2024-09-12 16:47:23 +0000 UTC 2024-09-12 16:47:23 +0000 UTC

使用 Arrays.sort() 方法根据您自己的规则对 Java 数组进行排序

  • 772

例如,有一个数组int:{0, -14, 191, 161, 19, 144, 195, 1}。

我想使用方法按绝对值Arrays.sort()对数组进行排序,是否可以使用比较器来执行此操作?谢谢大家。

java
  • 2 2 个回答
  • 42 Views

2 个回答

  • Voted
  1. Best Answer
    Nowhere Man
    2024-09-12T17:25:08Z2024-09-12T17:25:08Z

    使用比较器对数组进行排序不适用于原始类型的数组int[],long[]等等double[],因此对于自定义排序,您必须将数组转换为列表List<Integer>或数组Integer[],使用方法对其进行排序Arrays.sort(T[] arr, Comparator<? super T>) c,然后将其转换回原语数组。

    在这种情况下,您应该传递一个函数来转换为原语,而不是比较器,Integer在此基础上您可以使用 构建比较器Comparator.comparingInt(ToIntFunction<? super T>) fn。

    public static void sortIntArray(int[] arr, ToIntFunction<Integer> c) {
        Integer[] ints = new Integer[arr.length];
        Arrays.setAll(ints, i -> arr[i]);
        Arrays.sort(ints, Comparator.comparingInt(c));
        Arrays.setAll(arr, i -> ints[i]);
    }
    

    您还可以使用 Stream API 并返回一个新的排序数组,但请注意,它IntStream也不支持自定义排序,您必须Stream<Integer>使用以下方法将其转换为然后再返回Stream::mapToInt:

    public static int[] sortInts(int[] arr, ToIntFunction<Integer> c) {
        return Arrays.stream(arr)                // IntStream
            .boxed()                             // Stream<Integer>
            .sorted(Comparator.comparingInt(c))  // Stream<Integer>
            .mapToInt(Integer::intValue)         // IntStream
            .toArray();                          // int[]
    }
    

    测试:

    int[] arr = {0, -14, 191, 161, 19, 144, 195, 1};
    sortIntArray(arr, Math::abs);
    // или arr = sortInts(arr, Math::abs);
    System.out.println(Arrays.toString(arr));
    

    结论:

    [0, 1, -14, 19, 144, 161, 191, 195]
    

    同样,您可以传递一个用于自定义排序的方法IntUnaryOperator,该方法接收并返回 type 的结果int,然后在调用比较器时,您需要传递一个指向相应方法的链接IntUnaryOperator::applyAsInt:

    public static int[] sortInts(IntUnaryOperator fun, int... arr) {    
        return Arrays.stream(arr)
            .boxed()
            .sorted(Comparator.comparingInt(fun::applyAsInt))
            // аналогия с явным анбоксингом
            // .sorted(Comparator.comparingInt(i -> fun.applyAsInt(i.intValue())))
            .mapToInt(Integer::intValue)
            .toArray();
    }
    
    • 4
  2. Stanislav Volodarskiy
    2024-09-12T20:06:27Z2024-09-12T20:06:27Z

    Java 中有一个棘手的问题:您无法使用比较器对基元数组进行排序。标准库提供的方法涉及数组内容的两个副本。您将数据复制到数组或对象集合中,对其进行排序,然后将其复制回来。我想解决问题而不复制。

    有这样一种方法:让我们创建一个AbstractList看起来像列表的后继者Integer,但将数据存储在数组中。如果这样的后继被排序,则存储数据的数组将被排序。

    import java.util.Arrays;
    import java.util.AbstractList;
    import java.util.Comparator;
    
    public class Temp {
        public static void main(String[] args) {
            int[] array = {0, -14, 191, 161, 19, 144, 195, 1};
        
            System.out.println(Arrays.toString(array));
            sortArray(array, Comparator.comparingInt(Math::abs));
            System.out.println(Arrays.toString(array));
        }
    
        public static void sortArray(int[] array, Comparator<? super Integer> c) {
            new IntList(array).sort(c);
        }
    
        private static class IntList extends AbstractList<Integer> {
            private final int[] array;
    
            IntList(int[] array) { this.array = array; }
    
            @Override
            public Integer get(int i) { return array[i]; }
    
            @Override
            public int size() { return array.length; }
    
            @Override
            public Integer set(int i, Integer v) {
                int old = array[i];
                array[i] = v;
                return old;
            }
        }
    }
    

    一切正常:

    $ javac Temp.java && java Temp
    [0, -14, 191, 161, 19, 144, 195, 1]
    [0, 1, -14, 19, 144, 161, 191, 195]
    

    如果你不怕匿名类,代码可以写得更短:

    import java.util.Arrays;
    import java.util.AbstractList;
    import java.util.Comparator;
    
    public class Temp {
        public static void main(String[] args) {
            int[] array = {0, -14, 191, 161, 19, 144, 195, 1};
        
            System.out.println(Arrays.toString(array));
            sortArray(array, Comparator.comparingInt(Math::abs));
            System.out.println(Arrays.toString(array));
        }
    
        public static void sortArray(int[] array, Comparator<? super Integer> c) {
            new AbstractList<Integer>() {
                @Override
                public Integer get(int i) { return array[i]; }
    
                @Override
                public int size() { return array.length; }
    
                @Override
                public Integer set(int i, Integer v) {
                    int old = array[i];
                    array[i] = v;
                    return old;
                }
            }.sort(c);
        }
    }
    
    • 2

相关问题

  • wpcap 找不到指定的模块

  • 如何以编程方式从桌面应用程序打开 HTML 页面?

  • Android Studio 中的 R.java 文件在哪里?

  • HashMap 初始化

  • 如何使用 lambda 表达式通过增加与原点的距离来对点进行排序?

  • 最大化窗口时如何调整元素大小?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5