Wend看源码-Java-Arrays 工具集学习

news2025/1/6 1:46:07

摘要

  java.util.Arrays 是 Java 标准库中的一个实用工具类,它提供了各种静态方法来操作数组,包括排序、搜索、比较、填充等。这些方法简化了对数组的操作,并且在很多情况下可以提高代码的可读性和效率。以下是关于Arrays类中提供的一些主要方法的总结。

Sort(排序)

        对指定的数组进行升序排序。Collection接口和List 接口中的 sort 方法都是基于Arrays.sort方法实现的。 当你调用Arrays.sort()时,内部逻辑会自动选择最适合输入数据类型的排序算法:

  • 对于对象数组(实现了Comparable接口的对象),它使用ComparableTimSort
  • 对于带有显式比较器的对象数组,它也使用TimSort,但是通过提供比较器来进行元素间的比较。
  • 对于基本类型的数组(例如int[]double[]等),它使用DualPivotQuicksort。

示例代码

package person.wend.javalearnexample.util;

public class ArraysExample {

    public static void main(String[] args) {
        numberSort();
        objectSort();
    }

    public static void numberSort() {
        // 数字排序
        int[] numbers = { 3, 1, 4, 1, 5, 9, 2, 6 };
        java.util.Arrays.sort(numbers);
        for (int i : numbers) {
            System.out.print(i + " ");
        }
        System.out.println();
    }

    public static void objectSort(){
        // 对象排序
        String[] strings = { "Hello", "World", "Java" };
        java.util.Arrays.sort(strings);
        for (String s : strings) {
            System.out.print(s + " ");
        }
        System.out.println();
    }
}

排序算法 TimSort

        TimSort是一种混合排序算法,源自合并排序和插入排序。它是由Tim Peters在2002年为Python编程语言发明的,并且后来被Java采用作为默认的排序算法(从Java 7开始)。TimSort旨在利用真实世界数据中常见的模式来提高性能。它首先识别出已经有序的数据段(称为“runs”),然后以一种高效的方式合并这些段。对于大多数实际数据集来说,TimSort的表现非常好,其平均和最坏情况下的时间复杂度都是O(n log n)。

ComparableTimSort

      ComparableTimSort是TimSort的一个变体,专门用于处理实现了Comparable接口的对象数组或列表。这意味着数组中的元素能够自行比较大小,不需要额外提供比较器。Java的Arrays.sort(T[] a)List.sort(Comparator<? super T> c)(当没有提供自定义比较器时)使用这个变体。

排序算法 DualPivotQuicksort

        DualPivotQuicksort是快速排序的一种变体,由Vladimir Yaroslavskiy提出,用于改进传统的单轴快速排序。与标准的快速排序不同,它选择了两个枢轴点而不是一个,从而将数组分为三个部分。这种算法通常比传统快速排序更有效率,特别是对于包含大量重复元素的数据集。从Java 7开始,Arrays.sort()对基本类型(如int、double等)使用了DualPivotQuicksort。

binarySearch(二分搜索)

  Arrays.binarySearch()用于在一个已经排序的数组中执行二分查找(binary search)。该方法可以对基本类型数组和对象数组进行高效的搜索。对于对象数组,要求这些对象实现了 Comparable 接口或者提供了一个 Comparator 来定义元素之间的比较规则。

示例代码

public static void binarySearch() {
        // 创建一个整数数组
        int[] numbers = {3, 6, 2, 8, 4, 7, 5, 1};

        // 使用 binarySearch 查找元素 5
        int index = Arrays.binarySearch(numbers, 5);

        // 打印查找结果
        System.out.println("元素 5 的索引位置为:" + index);
    }

注意事项

  • 数组必须是已排序的。如果数组没有排序,那么结果是不确定的,可能会返回错误的结果。

  • 对于对象数组,数组中的元素类型必须实现Comparable接口,这样才能确定元素之间的大小关系,以便进行二分查找。如果没有实现Comparable接口,会在运行时抛出ClassCastException异常。

equals

  Arrays.equals() 用于比较两个一维数组的内容是否相等。它会逐一比较两个数组中的元素,如果所有对应位置上的元素都相等,则返回 true;否则返回 false。对于多维数组,equals() 只比较顶层元素的引用,而不是递归地比较内部数组的内容。

deepEquals

  Arrays.deepEquals() 方法不仅比较顶层元素,还会递归地比较多维数组中每个子数组的内容,直到所有的嵌套层级都被检查完毕。这对于包含其他数组的对象数组来说是非常有用的,因为它确保了整个结构的深度相等性。

示例代码

 public static void equalsTest(){
        int[] array1 = {1, 2, 3};
        int[] array2 = {1, 2, 3};
        int[] array3 = {3, 2, 1};

        // 比较两个相同内容的一维数组
        System.out.println("array1 and array2 are equal: " + Arrays.equals(array1, array2)); // true

        // 比较两个不同顺序的一维数组
        System.out.println("array1 and array3 are equal: " + Arrays.equals(array1, array3)); // false

        // 对于对象类型的数组,比较的是对象的内容(假设实现了正确的 equals 方法)
        String[] stringArray1 = {"hello", "world"};
        String[] stringArray2 = {"hello", "world"};

        System.out.println("stringArray1 and stringArray2 are equal: " + Arrays.equals(stringArray1, stringArray2)); // true


        Integer[][] array4 = {{1, 2}, {3, 4}};
        Integer[][] array5 = {{1, 2}, {3, 4}};
        Integer[][] array6 = {{1, 2}, {4, 3}};

        // 使用 Arrays.deepEquals() 比较两个相同内容的二维数组
        System.out.println("array1 and array2 are deeply equal: " + Arrays.deepEquals(array4, array5)); // true

        // 使用 Arrays.deepEquals() 比较两个不同内容的二维数组
        System.out.println("array1 and array3 are deeply equal: " + Arrays.deepEquals(array4, array6)); // false

        // 对于更复杂的数据结构,比如包含其他数组的对象数组
        Object[] complexArray1 = new Object[]{"hello", new Integer[]{1, 2}, new String[]{"a", "b"}};
        Object[] complexArray2 = new Object[]{"hello", new Integer[]{1, 2}, new String[]{"a", "b"}};

        System.out.println("complexArray1 and complexArray2 are deeply equal: " + Arrays.deepEquals(complexArray1, complexArray2)); // true
    }

 fill

  Arrays.fill() 方法用于将指定的值填充到整个数组或数组的一部分。它是一个非常方便的方法,可以快速初始化数组或更新现有数组的内容,而不需要使用循环来逐个设置元素。

示例代码

 public static void fillTest() {
        // 创建一个整型数组并用 7 填充
        int[] numbers = new int[5];
        Arrays.fill(numbers, 7);
        System.out.println("Filled array with 7: " + Arrays.toString(numbers)); // [7, 7, 7, 7, 7]

        // 创建一个字符串数组并用 "hello" 填充
        String[] greetings = new String[3];
        Arrays.fill(greetings, "hello");
        System.out.println("Filled string array: " + Arrays.toString(greetings)); // [hello, hello, hello]

        // 创建一个整型数组并部分填充
        int[] numbers2 = {1, 2, 3, 4, 5};
        Arrays.fill(numbers2, 1, 4, 8); // 从索引 1 到 3(不包括 4)的元素被替换为 8
        System.out.println("Partially filled array: " + Arrays.toString(numbers2)); // [1, 8, 8, 8, 5]

        // 创建一个字符数组并部分填充
        char[] chars = {'a', 'b', 'c', 'd', 'e'};
        Arrays.fill(chars, 2, 5, 'z'); // 从索引 2 到 4(不包括 5)的元素被替换为 'z'
        System.out.println("Partially filled char array: " + Arrays.toString(chars)); // [a, b, z, z, z]
    }

copyOf

  Arrays.copyOf 方法用于复制指定的数组,截断或填充(如有必要),以使副本具有指定的长度。如果原数组的长度小于新数组的长度,则填充 null(对于对象数组)或相应的默认值(对于基本类型数组,比如 0、false 等)。如果原数组的长度大于新数组的长度,则只复制指定长度内的元素。


copyOfRange

  Arrays.copyOfRange 方法用于复制指定数组的指定范围到新数组中。这个方法允许你指定开始索引(包含)和结束索引(不包含)来复制数组的一部分。

示例代码

public static void copyOfTest() {
        String[] original = {"Apple", "Banana", "Cherry", "Date"};
        String[] copy = Arrays.copyOf(original, 2); // 复制前两个元素
        System.out.println(Arrays.toString(copy)); // 输出: [Apple, Banana]

        String[] longerCopy = Arrays.copyOf(original, 6); // 原数组长度小于新长度,填充null
        System.out.println(Arrays.toString(longerCopy)); // 输出: [Apple, Banana, Cherry, Date, null, null]
        // copyOfRange
        String[] copyRange = Arrays.copyOfRange(original, 1, 3); // 复制索引1到索引2(不包括索引3)的元素
        System.out.println(Arrays.toString(copyRange)); // 输出: [Banana, Cherry]
    }


asList

  Arrays.asList()用于将一个数组转换为一个固定大小的List集合。这个方法提供了一种便捷的方式,使得可以使用一些List接口的方法来操作数组元素。

示例代码

  • 基本数据类型数组转换:对于基本数据类型数组,如int[]double[]等,基本数据类型数组在作为可变参数传递时,被视为一个单独的对象。
int[] intArray = {1, 2, 3};
List<int[]> list = Arrays.asList(intArray);
// 此时list中只有一个元素,就是intArray这个数组本身
System.out.println(list.size()); // 输出1
  • 如果要将基本数据类型数组转换为包含基本数据类型元素的List,可以先将基本数据类型数组转换为对应的包装类型数组,例如:
Integer[] integerArray = new Integer[intArray.length];
for (int i = 0; i < intArray.length; i++) {
    integerArray[i] = intArray[i];
}
List<Integer> integerList = Arrays.asList(integerArray);
System.out.println(integerList.size()); // 输出3
  • 对象数组转换示例:对于对象数组,使用就比较直接。例如,对于String数组:
String[] stringArray = {"apple", "banana", "cherry"};
List<String> stringList = Arrays.asList(stringArray);
System.out.println(stringList.size()); // 输出3
System.out.println(stringList.get(1)); // 输出banana

hashCode

  Arrays.hashCode() 方法为单层数组计算哈希码。该方法会遍历数组中的每一个元素,并将这些元素的哈希码组合成一个单一的哈希值。这个过程确保了即使两个不同的数组实例包含相同的元素序列,它们也会有相同的哈希码,从而可以正确地用作哈希表中的键或集合中的成员。

deepHashCode

  Arrays.deepHashCode() 方法则进一步处理多维数组,递归地计算每个子数组的哈希码。这对于包含其他数组的对象数组特别有用,因为它不仅考虑顶层元素,还深入到每一层嵌套的数组,确保整个结构的内容都被纳入哈希码的计算之中。

示例代码

 public static void hashCodeTest(){
        // 计算字符串数组的哈希码
        String[] array1 = {"apple", "banana", "cherry"};
        System.out.println("Hash code of array1: " + Arrays.hashCode(array1));

        // 对于基本类型数组,使用相应的 hashCode 方法
        int[] numbers = {1, 2, 3};
        System.out.println("Hash code of numbers: " + Arrays.hashCode(numbers));
        // 示例 2 deepHashCode
        // 创建一个二维字符串数组并计算其深哈希码
        String[][] array2D = {{"apple", "banana"}, {"cherry", "date"}};
        System.out.println("Deep hash code of 2D array: " + Arrays.deepHashCode(array2D));

        // 对于更复杂的数据结构,比如包含其他数组的对象数组
        Object[] complexArray = new Object[]{"hello", new Integer[]{1, 2}, new String[]{"a", "b"}};
        System.out.println("Deep hash code of complex array: " + Arrays.deepHashCode(complexArray));

    }

toString

 toString 方法用于返回指定数组内容的字符串表示形式。该方法适用于任何类型的数组,包括基本类型数组和对象数组。

deepToString

 deepToString 方法用于返回多维数组(即数组的数组)的字符串表示形式。当数组是嵌套的,toString 方法只能打印出最外层数组的引用,而 deepToString 能够递归地打印出所有层的元素。

示例代码

 public static void toStringTest(){
        int[] array = {1, 2, 3, 4, 5};
        String arrayString = Arrays.toString(array);
        System.out.println(arrayString); // 输出: [1, 2, 3, 4, 5]

        int[][] deepArray = {{1, 2}, {3, 4, 5}, {6}};
        String deepArrayString = Arrays.deepToString(deepArray);
        System.out.println(deepArrayString); // 输出: [[1, 2], [3, 4, 5], [6]]
    }

JDK 8 新增方法

parallelSort(并发排序)

  Arrays.parallelSort 是 Java 8+ 标准库提供的一个方法,用于对数组进行并行排序。它利用了 Java 的 Fork/Join 框架来实现多线程并行处理,可以加速大数组的排序操作。与 Arrays.sort() 不同,parallelSort() 方法旨在充分利用多核处理器的能力来提高性能。

示例代码

import java.util.Arrays;

public class ParallelSortExample {
    public static void main(String[] args) {
        int[] array = {5, 2, 8, 1, 9, 3};

        // 使用 parallelSort() 对数组进行排序
        Arrays.parallelSort(array);

        // 输出排序后的数组
        System.out.println(Arrays.toString(array));
    }
}

ArraysParallelSortHelpers

        这个类被用于辅助Arrays.parallelSort的实现,包含了用于并行排序的辅助方法和静态内部类。ArraysParallelSortHelpers 主要用于将排序任务分割成更小的任务,并在多个处理器核心上并行执行它们。

  1. 任务分割:ArraysParallelSortHelpers 将大数组分割成多个子数组,每个子数组可以由一个单独的线程进行排序。

  2. 任务合并:在子数组被排序后,ArraysParallelSortHelpers 提供了合并这些子数组的方法,以生成最终排序好的大数组。

  3. 工作窃取算法:为了提高效率,ArraysParallelSortHelpers 使用了工作窃取算法。这意味着空闲的线程可以从其他忙碌线程的任务队列中“窃取”任务。

parallelSort 与Sort 对比

  • 单线程 vs. 多线程:sort() 是一个单线程方法,而 parallelSort() 则会创建多个线程来进行并行排序。

  • 性能差异:对于较小的数组,sort() 可能比 parallelSort() 更快,因为后者需要额外的开销来设置和管理线程池。然而,对于较大的数组,parallelSort() 可以通过多线程并发执行来提供更好的性能。

  • 排序算法:sort() 对于原始类型(如 int, long 等)使用双轴快速排序算法,对于对象数组则使用 TimSort 算法。parallelSort() 在内部根据情况选择适当的算法,并且为了并行化可能会使用不同的策略。

  • 使用场景

    • sort():适用于小规模数据集或者当你的应用程序已经有很多活跃线程时,避免引入更多线程带来的额外开销。

    • parallelSort():适用于大规模数据集并且运行在多核处理器上的环境,能够从多线程中受益以减少排序时间。

parallelPrefix(前缀计算)

  Arrays.parallelPrefix()方法是 Java 8 中引入的一个并行数组操作方法。它用于对给定的数组进行前缀计算,计算方式是基于一个指定的二元操作符。该方法可以利用多核处理器的并行计算能力,在合适的场景下提高计算效率。

工作原理

  • 假设我们有一个数组[a, b, c, d],在执行parallelPrefix操作时,对于二元操作符op,计算过程如下:

  • 首先,计算第一个元素和第二个元素的结果,即newArray[1]=op.apply(array[0], array[1]),新数组的第一个元素通常保持不变(取决于操作符)。

  • 然后,计算新的第二个元素和第三个元素的结果,即newArray[2]=op.apply(newArray[1], array[2])

  • 以此类推,最后得到一个经过前缀计算后的数组。例如,如果操作符是加法,对于数组[1, 2, 3, 4],计算后的数组为[1, 1 + 2, (1 + 2)+3, ((1 + 2)+3)+4],即[1, 3, 6, 10]

示例代码

 public static void parallelPrefixTest(){
        // 创建一个整数数组
        int[] numbers = {1, 2, 3, 4, 5};

        // 使用 parallelPrefix 计算数组的前缀和
        Arrays.parallelPrefix(numbers, (left, right) -> left + right);

        // 打印计算结果
        System.out.println(Arrays.toString(numbers));
    }

setAll(设置新值)

  Arrays.setAll() 方法使用单线程来顺序地为数组中的每一个位置设置一个新值。它接受一个数组和一个 IntUnaryOperator 接口的实例作为参数,后者定义了一个操作,该操作接收一个整数参数(即数组索引)并返回一个新的整数值来填充对应的数组位置。

parallelSetAll(并行设置新值)

  Arrays.parallelSetAll() 方法与 setAll() 类似,但它利用 Java 的 Fork/Join 框架来并行化任务执行,从而加速大数组的填充过程。这个方法会尝试将数组分割成多个部分,并在不同的线程上同时应用生成器函数来填充这些部分。对于小数组或者只有一个处理器核心的情况下,parallelSetAll() 可能不会提供性能优势,甚至可能比 setAll() 更慢,因为并行处理引入了额外的开销。

示例代码

public static void setAllExample(){
        // 使用 setAll 初始化一个整型数组,每个元素是其索引的平方
        int[] squares = new int[5];
        Arrays.setAll(squares, i -> i * i);
        System.out.println("Squares: " + Arrays.toString(squares)); // [0, 1, 4, 9, 16]

        // 使用 setAll 初始化一个字符串数组,每个元素是其索引的字符表示
        String[] indexedStrings = new String[3];
        Arrays.setAll(indexedStrings, Integer::toString);
        System.out.println("Indexed strings: " + Arrays.toString(indexedStrings)); // [0, 1, 2]

        // 使用 parallelSetAll 并行初始化一个大整型数组,每个元素是其索引的立方
        int[] cubes = new int[1000000];
        Arrays.parallelSetAll(cubes, i -> i * i * i);

        // 打印前五个元素作为示例
        System.out.println("First five cubes: " + Arrays.toString(Arrays.copyOfRange(cubes, 0, 5))); // [0, 1, 8, 27, 64]

        // 对于对象数组,可以使用更复杂的生成逻辑
        String[] complexObjects = new String[10];
        Arrays.parallelSetAll(complexObjects, i -> "Object-" + i);
        System.out.println("Complex objects: " + Arrays.toString(complexObjects));
    }

spliterator

  spliterator是 Java 8 中引入的一个方法,用于获取数组的可拆分迭代器(Spliterator)。Spliterator 是一个用于遍历和分割数据源的接口,它可以用于并行处理数据。Arrays类中的spliterator方法提供了一种机制,使得可以将数组元素以一种能够支持并行处理的方式进行迭代。

  • 该方法返回一个Spliterator接口的实现对象,这个对象可以用于遍历数组元素。它支持多种操作,如tryAdvance(逐个元素尝试前进并执行操作)、forEachRemaining(对剩余元素执行操作)等。

  • 更重要的是,Spliterator 可以被分割,这对于并行处理非常关键。例如,在并行流处理中,可以将数据源分割成多个部分,每个部分可以由不同的线程处理,从而提高处理效率。它有一个trySplit方法,用于尝试将 Spliterator 分割成两个部分。如果分割成功,返回一个新的 Spliterator 代表分割后的一部分,原 Spliterator 则代表另一部分;如果无法分割(如数组元素太少等情况),则返回null

示例代码

 public static void spliteratorExample() {
        // 创建一个整数数组
        int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

        // 使用 spliterator() 方法创建一个 Spliterator 对象
        java.util.Spliterator<Integer> spliterator = Arrays.spliterator(numbers);

        // 使用 tryAdvance() 方法遍历 Spliterator
        System.out.println("Traversing the Spliterator:");
        spliterator.tryAdvance(System.out::println);

        // 使用 forEachRemaining() 方法遍历剩余元素
        spliterator.forEachRemaining(System.out::println);

        // 使用 trySplit() 方法拆分 Spliterator
        java.util.Spliterator<Integer> split = spliterator.trySplit();

        // 使用 tryAdvance() 方法遍历拆分后的 Spliterator
        System.out.println("Traversing the split Spliterator:");
        if (split != null) {
            split.tryAdvance(System.out::println);
            split.forEachRemaining(System.out::println);
        }

        // 使用 estimateSize() 方法获取剩余元素数量
        System.out.println("Remaining elements in the original Spliterator: " + spliterator.estimateSize());
        // 使用 characteristics() 方法获取 Spliterator 的特性
        System.out.println("Characteristics of the original Spliterator: " + spliterator.characteristics());
        // 使用 getExactSizeIfKnown() 方法获取确切元素数量
        System.out.println("Exact size of the original Spliterator: " + spliterator.getExactSizeIfKnown());
        // 使用 hasCharacteristics() 方法检查 Spliterator 的特性
        System.out.println("The original Spliterator is SIZED: " + spliterator.hasCharacteristics(java.util.Spliterator.SIZED));
    }

stream

  stream方法是 Java 8 中非常重要的一个特性相关的方法,它允许将数组转换为流(Stream)。流是一种用于处理元素序列的高级抽象,支持一系列的中间操作(如filtermap等)和终端操作(如forEachreduce等),可以让开发者以一种更函数式的方式来处理数据。

示例代码

public static void streamTest(){
        String[] stringArray = {"apple", "banana", "cherry", "date"};
        Stream<String> stream = Arrays.stream(stringArray);
        stream.filter(str -> str.length() > 5)
                .map(String::toUpperCase)
                .forEach(System.out::println);
    }

        在这个示例中,首先将String数组stringArray转换为Stream<String>,然后使用filter操作过滤出长度大于5的字符串(这里只有bananacherry),接着使用map操作将过滤后的字符串转换为大写形式,最后使用forEach操作将结果打印出来,输出为BANANACHERRY

JDK 9 新增方法

compare

  Arrays.compare()方法用于比较两个数组。它会根据数组中元素的顺序,从第一个元素开始逐个比较,直到找到不同的元素或者遍历完整个数组。这个方法返回一个整数值来表示两个数组的大小关系,返回值的规则遵循Comparator接口的一般约定。

compareUnsigned

 Arrays.compareUnsigned()方法主要用于无符号比较两个数组,特别是在处理无符号数据类型(如byteshortintlong)时非常有用。它和compare方法类似,但在比较过程中会将数据视为无符号数。

示例代码

  public static void compareTest(){
        int[] array1 = {1, 2, 3};
        int[] array2 = {1, 2, 4};
        int result = Arrays.compare(array1, array2);
        System.out.println("比较结果: " + result);

        // 示例 2 compareUnsigned
        int result2 = Arrays.compareUnsigned(array1, array2);
        System.out.println("比较结果(无符号比较): " + result2);

    }

mismatch

  mismatch() 方法用于比较两个数组,并找到第一个不匹配(即元素值不同的位置)。如果两个数组在所有对应位置上的元素都相等,则返回 -1;否则,返回第一个不同元素的索引。对于长度不同的数组,mismatch() 会返回较短数组的长度,因为超出部分默认视为不匹配。

  mismatch() 方法适用于基本类型数组和对象数组,并且能够处理多维数组的情况。它提供了一种高效的方式来定位两个数组之间的差异点,这对于调试、测试以及数据验证等场景非常有用。

示例代码

 public static void missMatchTest() {
        // 创建两个整型数组进行比较
        int[] array1 = {1, 2, 3, 4, 5};
        int[] array2 = {1, 2, 0, 4, 5};

        // 使用 mismatch 查找第一个不匹配的位置
        int index = Arrays.mismatch(array1, array2);
        System.out.println("First mismatch at index: " + index); // 输出 2,因为第三个元素不同

        // 如果两个数组完全相同
        int[] array3 = {1, 2, 3, 4, 5};
        index = Arrays.mismatch(array1, array3);
        System.out.println("First mismatch at index: " + index); // 输出 -1,表示没有不匹配的地方
    }

参考文献/AIGC

通义tongyi.ai_你的全能AI助手-通义千问

豆包

相关推荐

        JavaUsefulMode: 基于Java 语言的自定义实用工具集

        JavaUsefulMode是小编编写Java方向学习专栏时的代码示例汇总总结,其中内容包含了该篇文章所涉及的Java代码示例。感兴趣的小伙伴可以直接下载学习。


Wend看源码-Java.util 工具类学习(上)-CSDN博客

Wend看源码-Java.util 工具类学习(下)-CSDN博客

Wend看源码-Java-Collections 工具集学习-CSDN博客

Wend看源码-Java-Executor异步执行器学习-CSDN博客

Wend看源码-Java-fork/Join并行执行任务框架学习-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2270663.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构(ing)

学习内容 指针 指针的定义&#xff1a; 指针是一种变量&#xff0c;它的值为另一个变量的地址&#xff0c;即内存地址。 指针在内存中也是要占据位置的。 指针类型&#xff1a; 指针的值用来存储内存地址&#xff0c;指针的类型表示该地址所指向的数据类型并告诉编译器如何解…

实践:事件循环

实践&#xff1a;事件循环 代码示例 console.log(1); setTimeout(() > console.log(2), 0); Promise.resolve(3).then(res > console.log(res)); console.log(4);上述的代码的输出结果是什么 1和4肯定优先输出&#xff0c;因为他们会立即方式堆栈的执行上下文中执行&am…

从零开始开发纯血鸿蒙应用之逻辑封装

从零开始开发纯血鸿蒙应用 一、前言二、逻辑封装的原则三、实现 FileUtil1、统一的存放位置2、文件的增删改查2.1、文件创建与文件保存2.2、文件读取2.2.1、读取内部文件2.2.2、读取外部文件 3、文件删除 四、总结 一、前言 应用的动态&#xff0c;借助 UI 响应完成&#xff0…

ESP32 I2S音频总线学习笔记(一):初识I2S通信与配置基础

文章目录 简介为什么需要I2S&#xff1f;关于音频信号采样率分辨率音频声道 怎样使用I2S传输音频&#xff1f;位时钟BCLK字时钟WS串行数据SD I2S传输模型I2S通信格式I2S格式左对齐格式右对齐格式 i2s基本配置i2s 底层API加载I2S驱动设置I2S使用的引脚I2S读取数据I2S发送数据卸载…

CSS 中 content换行符实现打点 loading 正在加载中的效果

我们动态加载页面内容的时候&#xff0c;经常会使用“正在加载中…”这几个字&#xff0c;基本上&#xff0c;后面的 3 个点都是静态的。静态的问题在于&#xff0c;如果网络不流畅&#xff0c;加载时间比较长&#xff0c;就会给人有假死的 感觉&#xff0c;但是&#xff0c;如…

25考研王道数据结构课后习题笔记

声明&#xff1a;以下内容来自于B栈知名up主–白话拆解数据结构 回答&#xff1a;为什么要做这个&#xff0c;因为我这个学期学完了数据结构&#xff0c;而且这个数据结构是408的重头&#xff0c;为什么选择25的&#xff0c;因为这个25考研刚刚结束&#xff0c;25相对成熟&…

小程序发版后,强制更新为最新版本

为什么要强制更新为最新版本&#xff1f; 在小程序的开发和运营过程中&#xff0c;强制用户更新到最新版本是一项重要的策略&#xff0c;能够有效提升用户体验并保障系统的稳定性与安全性。以下是一些主要原因&#xff1a; 1. 功能兼容 新功能或服务通常需要最新版本的支持&…

GRAPE——RLAIF微调VLA模型:通过偏好对齐提升机器人策略的泛化能力(含24年具身模型汇总)

前言 24年具身前沿模型大汇总 过去的这两年&#xff0c;工作之余&#xff0c;我狂写大模型与具身的文章&#xff0c;加之具身大火&#xff0c;每周都有各种朋友通过CSDN私我及我司「七月在线」寻求帮助/指导(当然&#xff0c;也欢迎各大开发团队与我司合作共同交付&#xff09…

0xc0000020错误代码怎么处理,Windows11、10坏图像错误0xc0000020的修复办法

“0xc0000020”是一种 Windows 应用程序错误代码&#xff0c;通常表明某些文件缺失或损坏。这可能是由于系统文件损坏、应用程序安装或卸载问题、恶意软件感染、有问题的 Windows 更新等原因导致的。 比如&#xff0c;当运行软件时&#xff0c;可能会出现类似“C:\xx\xxx.dll …

pycharm+anaconda创建项目

pycharmanaconda创建项目 安装&#xff1a; Windows下PythonPyCharm的安装步骤及PyCharm的使用-CSDN博客 详细Anaconda安装配置环境创建教程-CSDN博客 创建项目&#xff1a; 开始尝试新建一个项目吧&#xff01; 选择好项目建设的文件夹 我的项目命名为&#xff1a;pyth…

基于Pytorch和yolov8n手搓安全帽目标检测的全过程

一.背景 还是之前的主题&#xff0c;使用开源软件为公司搭建安全管理平台&#xff0c;从视觉模型识别安全帽开始。主要参考学习了开源项目 https://github.com/jomarkow/Safety-Helmet-Detection&#xff0c;我是从运行、训练、标注倒过来学习的。由于工作原因&#xff0c;抽空…

【PDF物流单据提取明细】批量PDF提取多个区域内容导出表格或用区域内容对文件改名,批量提取PDF物流单据单号及明细导出表格并改名的技术难点及小节

相关阅读及下载&#xff1a; PDF电子物流单据&#xff1a; 批量PDF提取多个区域局部内容重命名PDF或者将PDF多个局部内容导出表格&#xff0c;具体使用步骤教程和实际应用场景的说明演示https://mp.weixin.qq.com/s/uCvqHAzKglfr40YPO_SyNg?token720634989&langzh_CN扫描…

JavaWeb开发(五)Servlet-ServletContext

1. ServletContext 1.1. ServletContext简介 1.1.1. ServletContext定义 ServletContext即Servlet上下文对象&#xff0c;该对象表示当前的web应用环境信息。 1.1.2. 获取ServletContext对象: &#xff08;1&#xff09;通过ServletConfig的getServletContext()方法可以得到…

长时间序列预测算法---Informer

目录 一、传统的 Transformer 模型二、Informer原理2.1 Attention计算2.2 “积极”的Q筛选2.2.1 KL散度2.2.2 “懒惰”的q处理 2.3 Encoder结构2.4 Decoder结构2.4.1 Transformer的Decoder操作2.4.2 Informer的Decoder操作 2.5 Informer模型的改进 三、模型应用 时间序列相关参…

点击取消按钮,console出来数据更改了,页面视图没有更新

点击取消按钮&#xff0c;console出来数据更改了&#xff0c;页面视图没有更新 前言 实现效果&#xff1a;点击取消按钮&#xff0c;页面视图全部为空&#xff0c; 遇到的问题&#xff1a; 点击取消按钮&#xff0c;console出来数据更改了&#xff0c;SchemaJson 都是默认值啦…

RFID手持机与RFID工业平板在仓储物流管理系统中的选型

概述 随着物联网技术在仓储物流管理系统中的普及&#xff0c;RFID手持机与RFID工业平板作为基于RFID技术手持式读写器的两种重要终端设备形态&#xff0c;得到了广泛应用。尽管RFID手持机与RFID工业平板都具备读写 RFID标签的基本功能&#xff0c;使用场景较为类似&#xff0c…

UML之泛化、特化和继承

在UML&#xff08;统一建模语言&#xff09;中&#xff0c;泛化&#xff08;Generalization&#xff09;和特化&#xff08;Specialization&#xff09;是面向对象思想中继承&#xff08;Inheritance&#xff09;关系的重要概念&#xff0c;它们描述类与类&#xff08;或用例与…

vue 修改vant样式NoticeBar中的图标,不用插槽可以直接用图片

使用文档中是可以直接使用图片链接的 :left-icon"require(../../assets/newImages/noticeImg.png)" <html> .... <NoticeBarmode""color"#C6C6C6"background""v-if"global_info.site_bulletin":left-icon"r…

【漫话机器学习系列】028.CP

Mallows’ Cp&#xff1a;标准化公式解析与应用 Mallows’ Cp 是一种常用的模型选择工具&#xff0c;用于在一系列候选模型中权衡拟合度和复杂性&#xff0c;帮助我们选择性能最优的模型。本文将基于其标准化公式展开详细解析&#xff0c;并探讨其应用场景、实现方法、优点与局…

vs 2022 中xml 粘贴为Class 中,序列化出来的xml 的使用

上图是visual studio 2022 中使用的粘贴功能的菜单位置 在生成的xml 中&#xff0c;有些是类似如下类型的 [System.Serializable] [System.Xml.Serialization.XmlType] public class Item {private bool isVisibleField;private bool isVisibleFieldSpecified;[System.Xml.Se…