二十二、数组(5)

本章概要

  • 数组元素修改
  • 数组并行
  • Arrays 工具类
  • 数组拷贝
  • 数组比较
  • 流和数组

数组元素修改

传递给 Arrays.setAll() 的生成器函数可以使用它接收到的数组索引修改现有的数组元素:

ModifyExisting.java

import java.util.Arrays;import static com.example.test.ArrayShow.show;public class ModifyExisting {public static void main(String[] args) {double[] da = new double[7];Arrays.setAll(da, new Rand.Double()::get);show(da);Arrays.setAll(da, n -> da[n] / 100); // [1]show(da);}
}

在这里插入图片描述

Rand.java

import java.util.*;
import java.util.function.*;import static com.example.test.ConvertTo.primitive;public interface Rand {int MOD = 10_000;class Boolean implements Supplier<java.lang.Boolean> {SplittableRandom r = new SplittableRandom(47);@Overridepublic java.lang.Boolean get() {return r.nextBoolean();}public java.lang.Boolean get(int n) {return get();}public java.lang.Boolean[] array(int sz) {java.lang.Boolean[] result =new java.lang.Boolean[sz];Arrays.setAll(result, n -> get());return result;}}class Pboolean {public boolean[] array(int sz) {return primitive(new Boolean().array(sz));}}class Byteimplements Supplier<java.lang.Byte> {SplittableRandom r = new SplittableRandom(47);@Overridepublic java.lang.Byte get() {return (byte) r.nextInt(MOD);}public java.lang.Byte get(int n) {return get();}public java.lang.Byte[] array(int sz) {java.lang.Byte[] result =new java.lang.Byte[sz];Arrays.setAll(result, n -> get());return result;}}class Pbyte {public byte[] array(int sz) {return primitive(new Byte().array(sz));}}class Characterimplements Supplier<java.lang.Character> {SplittableRandom r = new SplittableRandom(47);@Overridepublic java.lang.Character get() {return (char) r.nextInt('a', 'z' + 1);}public java.lang.Character get(int n) {return get();}public java.lang.Character[] array(int sz) {java.lang.Character[] result =new java.lang.Character[sz];Arrays.setAll(result, n -> get());return result;}}class Pchar {public char[] array(int sz) {return primitive(new Character().array(sz));}}class Shortimplements Supplier<java.lang.Short> {SplittableRandom r = new SplittableRandom(47);@Overridepublic java.lang.Short get() {return (short) r.nextInt(MOD);}public java.lang.Short get(int n) {return get();}public java.lang.Short[] array(int sz) {java.lang.Short[] result =new java.lang.Short[sz];Arrays.setAll(result, n -> get());return result;}}class Pshort {public short[] array(int sz) {return primitive(new Short().array(sz));}}class Integerimplements Supplier<java.lang.Integer> {SplittableRandom r = new SplittableRandom(47);@Overridepublic java.lang.Integer get() {return r.nextInt(MOD);}public java.lang.Integer get(int n) {return get();}public java.lang.Integer[] array(int sz) {int[] primitive = new Pint().array(sz);java.lang.Integer[] result =new java.lang.Integer[sz];for (int i = 0; i < sz; i++) {result[i] = primitive[i];}return result;}}class Pint implements IntSupplier {SplittableRandom r = new SplittableRandom(47);@Overridepublic int getAsInt() {return r.nextInt(MOD);}public int get(int n) {return getAsInt();}public int[] array(int sz) {return r.ints(sz, 0, MOD).toArray();}}class Long implements Supplier<java.lang.Long> {SplittableRandom r = new SplittableRandom(47);@Overridepublic java.lang.Long get() {return r.nextLong(MOD);}public java.lang.Long get(int n) {return get();}public java.lang.Long[] array(int sz) {long[] primitive = new Plong().array(sz);java.lang.Long[] result =new java.lang.Long[sz];for (int i = 0; i < sz; i++) {result[i] = primitive[i];}return result;}}class Plong implements LongSupplier {SplittableRandom r = new SplittableRandom(47);@Overridepublic long getAsLong() {return r.nextLong(MOD);}public long get(int n) {return getAsLong();}public long[] array(int sz) {return r.longs(sz, 0, MOD).toArray();}}class Floatimplements Supplier<java.lang.Float> {SplittableRandom r = new SplittableRandom(47);@Overridepublic java.lang.Float get() {return (float) trim(r.nextDouble());}public java.lang.Float get(int n) {return get();}public java.lang.Float[] array(int sz) {java.lang.Float[] result =new java.lang.Float[sz];Arrays.setAll(result, n -> get());return result;}}class Pfloat {public float[] array(int sz) {return primitive(new Float().array(sz));}}static double trim(double d) {return((double) Math.round(d * 1000.0)) / 100.0;}class Double implements Supplier<java.lang.Double> {SplittableRandom r = new SplittableRandom(47);@Overridepublic java.lang.Double get() {return trim(r.nextDouble());}public java.lang.Double get(int n) {return get();}public java.lang.Double[] array(int sz) {double[] primitive =new Rand.Pdouble().array(sz);java.lang.Double[] result =new java.lang.Double[sz];for (int i = 0; i < sz; i++) {result[i] = primitive[i];}return result;}}class Pdouble implements DoubleSupplier {SplittableRandom r = new SplittableRandom(47);@Overridepublic double getAsDouble() {return trim(r.nextDouble());}public double get(int n) {return getAsDouble();}public double[] array(int sz) {double[] result = r.doubles(sz).toArray();Arrays.setAll(result,n -> result[n] = trim(result[n]));return result;}}class Stringimplements Supplier<java.lang.String> {SplittableRandom r = new SplittableRandom(47);private int strlen = 7; // Default lengthpublic String() {}public String(int strLength) {strlen = strLength;}@Overridepublic java.lang.String get() {return r.ints(strlen, 'a', 'z' + 1).collect(StringBuilder::new,StringBuilder::appendCodePoint,StringBuilder::append).toString();}public java.lang.String get(int n) {return get();}public java.lang.String[] array(int sz) {java.lang.String[] result =new java.lang.String[sz];Arrays.setAll(result, n -> get());return result;}}
}

ConvertTo.java

public interface ConvertTo {static boolean[] primitive(Boolean[] in) {boolean[] result = new boolean[in.length];for (int i = 0; i < in.length; i++) {result[i] = in[i]; // Autounboxing}return result;}static char[] primitive(Character[] in) {char[] result = new char[in.length];for (int i = 0; i < in.length; i++) {result[i] = in[i];}return result;}static byte[] primitive(Byte[] in) {byte[] result = new byte[in.length];for (int i = 0; i < in.length; i++) {result[i] = in[i];}return result;}static short[] primitive(Short[] in) {short[] result = new short[in.length];for (int i = 0; i < in.length; i++) {result[i] = in[i];}return result;}static int[] primitive(Integer[] in) {int[] result = new int[in.length];for (int i = 0; i < in.length; i++) {result[i] = in[i];}return result;}static long[] primitive(Long[] in) {long[] result = new long[in.length];for (int i = 0; i < in.length; i++) {result[i] = in[i];}return result;}static float[] primitive(Float[] in) {float[] result = new float[in.length];for (int i = 0; i < in.length; i++) {result[i] = in[i];}return result;}static double[] primitive(Double[] in) {double[] result = new double[in.length];for (int i = 0; i < in.length; i++) {result[i] = in[i];}return result;}// Convert from primitive array to wrapped array:static Boolean[] boxed(boolean[] in) {Boolean[] result = new Boolean[in.length];for (int i = 0; i < in.length; i++) {result[i] = in[i]; // Autoboxing}return result;}static Character[] boxed(char[] in) {Character[] result = new Character[in.length];for (int i = 0; i < in.length; i++) {result[i] = in[i];}return result;}static Byte[] boxed(byte[] in) {Byte[] result = new Byte[in.length];for (int i = 0; i < in.length; i++) {result[i] = in[i];}return result;}static Short[] boxed(short[] in) {Short[] result = new Short[in.length];for (int i = 0; i < in.length; i++) {result[i] = in[i];}return result;}static Integer[] boxed(int[] in) {Integer[] result = new Integer[in.length];for (int i = 0; i < in.length; i++) {result[i] = in[i];}return result;}static Long[] boxed(long[] in) {Long[] result = new Long[in.length];for (int i = 0; i < in.length; i++) {result[i] = in[i];}return result;}static Float[] boxed(float[] in) {Float[] result = new Float[in.length];for (int i = 0; i < in.length; i++) {result[i] = in[i];}return result;}static Double[] boxed(double[] in) {Double[] result = new Double[in.length];for (int i = 0; i < in.length; i++) {result[i] = in[i];}return result;}
}

ArrayShow.java

import java.util.*;public interface ArrayShow {static void show(Object[] a) {System.out.println(Arrays.toString(a));}static void show(boolean[] a) {System.out.println(Arrays.toString(a));}static void show(byte[] a) {System.out.println(Arrays.toString(a));}static void show(char[] a) {System.out.println(Arrays.toString(a));}static void show(short[] a) {System.out.println(Arrays.toString(a));}static void show(int[] a) {System.out.println(Arrays.toString(a));}static void show(long[] a) {System.out.println(Arrays.toString(a));}static void show(float[] a) {System.out.println(Arrays.toString(a));}static void show(double[] a) {System.out.println(Arrays.toString(a));}// Start with a description:static void show(String info, Object[] a) {System.out.print(info + ": ");show(a);}static void show(String info, boolean[] a) {System.out.print(info + ": ");show(a);}static void show(String info, byte[] a) {System.out.print(info + ": ");show(a);}static void show(String info, char[] a) {System.out.print(info + ": ");show(a);}static void show(String info, short[] a) {System.out.print(info + ": ");show(a);}static void show(String info, int[] a) {System.out.print(info + ": ");show(a);}static void show(String info, long[] a) {System.out.print(info + ": ");show(a);}static void show(String info, float[] a) {System.out.print(info + ": ");show(a);}static void show(String info, double[] a) {System.out.print(info + ": ");show(a);}
}

[1] Lambdas在这里特别有用,因为数组总是在lambda表达式的范围内。

数组并行

我们很快就不得不面对并行的主题。例如,“并行”一词在许多Java库方法中使用。您可能听说过类似“并行程序运行得更快”这样的说法,这是有道理的—当您可以有多个处理器时,为什么只有一个处理器在您的程序上工作呢? 如果您认为您应该利用其中的“并行”,这是很容易被原谅的。

要是这么简单就好了。不幸的是,通过采用这种方法,您可以很容易地编写比非并行版本运行速度更慢的代码。在你深刻理解所有的问题之前,并行编程看起来更像是一门艺术而非科学。
以下是简短的版本:用简单的方法编写代码。不要开始处理并行性,除非它成为一个问题。您仍然会遇到并行性。在本章中,我们将介绍一些为并行执行而编写的Java库方法。因此,您必须对它有足够的了解,以便进行基本的讨论,并避免出现错误。

在阅读并发编程这一章之后,您将更深入地理解它(但是,唉,这还远远不够。只是这些的话,充分理解这个主题是不可能的)。
在某些情况下,即使您只有一个处理器,无论您是否显式地尝试并行,并行实现是惟一的、最佳的或最符合逻辑的选择。它是一个可以一直使用的工具,所以您必须了解它的相关问题。

最好从数据的角度来考虑并行性。对于大量数据(以及可用的额外处理器),并行可能会有所帮助。但您也可能使事情变得更糟。

在本书的其余部分,我们将遇到不同的情况:

  • 1、所提供的惟一选项是并行的。这很简单,因为我们别无选择,只能使用它。这种情况是比较罕见的。
  • 2、有多个选项,但是并行版本(通常是最新的版本)被设计成在任何地方都可以使用(甚至在那些不关心并行性的代码中),如案例#1。我们将按预期使用并行版本。
  • 3、案例1和案例2并不经常发生。相反,您将遇到某些算法的两个版本,一个用于并行使用,另一个用于正常使用。我将描述并行的一个,但不会在普通代码中使用它,因为它也许会产生所有可能的问题。

流式编程产生优雅的代码。例如,假设我们想要创建一个数值由从零开始填充的长数组:

import java.util.stream.LongStream;import static com.example.test.ArrayShow.show;public class CountUpward {static long[] fillCounted(int size) {return LongStream.iterate(0, i -> i + 1).limit(size).toArray();}public static void main(String[] args) {long[] l1 = fillCounted(20); // No problemshow(l1);// On my machine, this runs out of heap space:// - long[] l2 = fillCounted(10_000_000);}
}

在这里插入图片描述

实际上可以存储到将近1000万,但是之后就会耗尽堆空间。常规的 setAll() 是有效的,但是如果我们能更快地处理如此大量的数字,那就更好了。
我们可以使用 setAll() 初始化更大的数组。如果速度成为一个问题,Arrays.parallelSetAll() 将(可能)更快地执行初始化(请记住并行性中描述的问题)。

import java.util.Arrays;public class ParallelSetAll {static final int SIZE = 10_000_000;static void intArray() {int[] ia = new int[SIZE];Arrays.setAll(ia, new Rand.Pint()::get);Arrays.parallelSetAll(ia, new Rand.Pint()::get);}static void longArray() {long[] la = new long[SIZE];Arrays.setAll(la, new Rand.Plong()::get);Arrays.parallelSetAll(la, new Rand.Plong()::get);}public static void main(String[] args) {intArray();longArray();}
}

数组分配和初始化是在单独的方法中执行的,因为如果两个数组都在 main() 中分配,它会耗尽内存(至少在我的机器上是这样。还有一些方法可以告诉Java在启动时分配更多的内存)。

Arrays工具类

您已经看到了 java.util.Arrays 中的 fill()setAll()/parallelSetAll() 。该类包含许多其他有用的 静态 程序方法,我们将对此进行研究。

概述:

  • asList(): 获取任何序列或数组,并将其转换为一个 列表集合 (集合章节介绍了此方法)。
  • copyOf():以新的长度创建现有数组的新副本。
  • copyOfRange():创建现有数组的一部分的新副本。
  • equals():比较两个数组是否相等。
  • deepEquals():多维数组的相等性比较。
  • stream():生成数组元素的流。
  • hashCode():生成数组的哈希值(您将在附录中了解这意味着什么:理解equals()和hashCode())。
  • deepHashCode(): 多维数组的哈希值。
  • sort():排序数组
  • parallelSort():对数组进行并行排序,以提高速度。
  • binarySearch():在已排序的数组中查找元素。
  • parallelPrefix():使用提供的函数并行累积(以获得速度)。基本上,就是数组的reduce()。
  • spliterator():从数组中产生一个Spliterator;这是本书没有涉及到的流的高级部分。
  • toString():为数组生成一个字符串表示。你在整个章节中经常看到这种用法。
  • deepToString():为多维数组生成一个字符串。你在整个章节中经常看到这种用法。对于所有基本类型和对象,所有这些方法都是重载的。

数组拷贝

与使用for循环手工执行复制相比,copyOf()copyOfRange() 复制数组要快得多。这些方法被重载以处理所有类型。

我们从复制 intInteger 数组开始:

Count.java

import java.util.*;
import java.util.function.*;import static com.example.test.ConvertTo.primitive;public interface Count {class Booleanimplements Supplier<java.lang.Boolean> {private boolean b = true;@Overridepublic java.lang.Boolean get() {b = !b;return java.lang.Boolean.valueOf(b);}public java.lang.Boolean get(int n) {return get();}public java.lang.Boolean[] array(int sz) {java.lang.Boolean[] result =new java.lang.Boolean[sz];Arrays.setAll(result, n -> get());return result;}}class Pboolean {private boolean b = true;public boolean get() {b = !b;return b;}public boolean get(int n) {return get();}public boolean[] array(int sz) {return primitive(new Boolean().array(sz));}}class Byteimplements Supplier<java.lang.Byte> {private byte b;@Overridepublic java.lang.Byte get() {return b++;}public java.lang.Byte get(int n) {return get();}public java.lang.Byte[] array(int sz) {java.lang.Byte[] result =new java.lang.Byte[sz];Arrays.setAll(result, n -> get());return result;}}class Pbyte {private byte b;public byte get() {return b++;}public byte get(int n) {return get();}public byte[] array(int sz) {return primitive(new Byte().array(sz));}}char[] CHARS ="abcdefghijklmnopqrstuvwxyz".toCharArray();class Characterimplements Supplier<java.lang.Character> {private int i;@Overridepublic java.lang.Character get() {i = (i + 1) % CHARS.length;return CHARS[i];}public java.lang.Character get(int n) {return get();}public java.lang.Character[] array(int sz) {java.lang.Character[] result =new java.lang.Character[sz];Arrays.setAll(result, n -> get());return result;}}class Pchar {private int i;public char get() {i = (i + 1) % CHARS.length;return CHARS[i];}public char get(int n) {return get();}public char[] array(int sz) {return primitive(new Character().array(sz));}}class Shortimplements Supplier<java.lang.Short> {short s;@Overridepublic java.lang.Short get() {return s++;}public java.lang.Short get(int n) {return get();}public java.lang.Short[] array(int sz) {java.lang.Short[] result =new java.lang.Short[sz];Arrays.setAll(result, n -> get());return result;}}class Pshort {short s;public short get() {return s++;}public short get(int n) {return get();}public short[] array(int sz) {return primitive(new Short().array(sz));}}class Integerimplements Supplier<java.lang.Integer> {int i;@Overridepublic java.lang.Integer get() {return i++;}public java.lang.Integer get(int n) {return get();}public java.lang.Integer[] array(int sz) {java.lang.Integer[] result =new java.lang.Integer[sz];Arrays.setAll(result, n -> get());return result;}}class Pint implements IntSupplier {int i;public int get() {return i++;}public int get(int n) {return get();}@Overridepublic int getAsInt() {return get();}public int[] array(int sz) {return primitive(new Integer().array(sz));}}class Longimplements Supplier<java.lang.Long> {private long l;@Overridepublic java.lang.Long get() {return l++;}public java.lang.Long get(int n) {return get();}public java.lang.Long[] array(int sz) {java.lang.Long[] result =new java.lang.Long[sz];Arrays.setAll(result, n -> get());return result;}}class Plong implements LongSupplier {private long l;public long get() {return l++;}public long get(int n) {return get();}@Overridepublic long getAsLong() {return get();}public long[] array(int sz) {return primitive(new Long().array(sz));}}class Floatimplements Supplier<java.lang.Float> {private int i;@Overridepublic java.lang.Float get() {return java.lang.Float.valueOf(i++);}public java.lang.Float get(int n) {return get();}public java.lang.Float[] array(int sz) {java.lang.Float[] result =new java.lang.Float[sz];Arrays.setAll(result, n -> get());return result;}}class Pfloat {private int i;public float get() {return i++;}public float get(int n) {return get();}public float[] array(int sz) {return primitive(new Float().array(sz));}}class Doubleimplements Supplier<java.lang.Double> {private int i;@Overridepublic java.lang.Double get() {return java.lang.Double.valueOf(i++);}public java.lang.Double get(int n) {return get();}public java.lang.Double[] array(int sz) {java.lang.Double[] result =new java.lang.Double[sz];Arrays.setAll(result, n -> get());return result;}}class Pdouble implements DoubleSupplier {private int i;public double get() {return i++;}public double get(int n) {return get();}@Overridepublic double getAsDouble() {return get(0);}public double[] array(int sz) {return primitive(new Double().array(sz));}}
}

ArrayCopying.java

import java.util.Arrays;import static com.example.test.ArrayShow.show;class Sup {// Superclassprivate int id;Sup(int n) {id = n;}@Overridepublic String toString() {return getClass().getSimpleName() + id;}
}class Sub extends Sup { // SubclassSub(int n) {super(n);}
}public class ArrayCopying {public static final int SZ = 15;public static void main(String[] args) {int[] a1 = new int[SZ];Arrays.setAll(a1, new Count.Integer()::get);show("a1", a1);int[] a2 = Arrays.copyOf(a1, a1.length); // [1]// Prove they are distinct arrays:Arrays.fill(a1, 1);show("a1", a1);show("a2", a2);// Create a shorter result:a2 = Arrays.copyOf(a2, a2.length / 2); // [2]show("a2", a2);// Allocate more space:a2 = Arrays.copyOf(a2, a2.length + 5);show("a2", a2);// Also copies wrapped arrays:Integer[] a3 = new Integer[SZ]; // [3]Arrays.setAll(a3, new Count.Integer()::get);Integer[] a4 = Arrays.copyOfRange(a3, 4, 12);show("a4", a4);Sub[] d = new Sub[SZ / 2];Arrays.setAll(d, Sub::new); // Produce Sup[] from Sub[]:Sup[] b = Arrays.copyOf(d, d.length, Sup[].class); // [4]show(b); // This "downcast" works fine:Sub[] d2 = Arrays.copyOf(b, b.length, Sub[].class); // [5]show(d2); // Bad "downcast" compiles but throws exception:Sup[] b2 = new Sup[SZ / 2];Arrays.setAll(b2, Sup::new);try {Sub[] d3 = Arrays.copyOf(b2, b2.length, Sub[].class); // [6]} catch (Exception e) {System.out.println(e);}}
}

在这里插入图片描述

[1] 这是复制的基本方法;只需给出返回的复制数组的大小。这对于编写需要调整存储大小的算法很有帮助。复制之后,我们把a1的所有元素都设为1,以证明a1的变化不会影响a2中的任何东西。

[2] 通过更改最后一个参数,我们可以缩短或延长返回的复制数组。

[3] copyOf()copyOfRange() 也可以使用包装类型。copyOfRange() 需要一个开始和结束索引。

[4] copyOf()copyOfRange() 都有一个版本,该版本通过在方法调用的末尾添加目标类型来创建不同类型的数组。我首先想到的是,这可能是一种从原生数组生成包装数组的方法,反之亦然。
但这没用。它的实际用途是“向上转换”和“向下转换”数组。也就是说,如果您有一个子类型(派生类型)的数组,而您想要一个基类型的数组,那么这些方法将生成所需的数组。

[5] 您甚至可以成功地“向下强制转换”,并从超类型的数组生成子类型的数组。这个版本运行良好,因为我们只是“upcast”。

[6] 这个“数组转换”将编译,但是如果类型不兼容,您将得到一个运行时异常。在这里,强制将基类型转换为派生类型是非法的,因为派生对象中可能有基对象中没有的属性和方法。

实例表明,原生数组和对象数组都可以被复制。但是,如果复制对象的数组,那么只复制引用—不复制对象本身。这称为浅拷贝(有关更多细节,请参阅附录:传递和返回对象)。

还有一个方法 System.arraycopy() ,它将一个数组复制到另一个已经分配的数组中。这将不会执行自动装箱或自动卸载—两个数组必须是完全相同的类型。

数组比较

数组 提供了 equals() 来比较一维数组,以及 deepEquals() 来比较多维数组。对于所有原生类型和对象,这些方法都是重载的。

数组相等的含义:数组必须有相同数量的元素,并且每个元素必须与另一个数组中的对应元素相等,对每个元素使用 equals()(对于原生类型,使用原生类型的包装类的 equals() 方法;例如,int的Integer.equals()。

import java.util.*;public class ComparingArrays {public static final int SZ = 15;static String[][] twoDArray() {String[][] md = new String[5][];Arrays.setAll(md, n -> new String[n]);for (int i = 0; i < md.length; i++) {Arrays.setAll(md[i], new Rand.String()::get);}return md;}public static void main(String[] args) {int[] a1 = new int[SZ], a2 = new int[SZ];Arrays.setAll(a1, new Count.Integer()::get);Arrays.setAll(a2, new Count.Integer()::get);System.out.println("a1 == a2: " + Arrays.equals(a1, a2));a2[3] = 11;System.out.println("a1 == a2: " + Arrays.equals(a1, a2));Integer[] a1w = new Integer[SZ], a2w = new Integer[SZ];Arrays.setAll(a1w, new Count.Integer()::get);Arrays.setAll(a2w, new Count.Integer()::get);System.out.println("a1w == a2w: " + Arrays.equals(a1w, a2w));a2w[3] = 11;System.out.println("a1w == a2w: " + Arrays.equals(a1w, a2w));String[][] md1 = twoDArray(), md2 = twoDArray();System.out.println(Arrays.deepToString(md1));System.out.println("deepEquals(md1, md2): " + Arrays.deepEquals(md1, md2));System.out.println("md1 == md2: " + Arrays.equals(md1, md2));md1[4][1] = "#$#$#$#";System.out.println(Arrays.deepToString(md1));System.out.println("deepEquals(md1, md2): " + Arrays.deepEquals(md1, md2));}
}

在这里插入图片描述

最初,a1和a2是完全相等的,所以输出是true,但是之后其中一个元素改变了,这使得结果为false。a1w和a2w是对一个封装类型数组重复该练习。

md1md2 是通过 twoDArray() 以相同方式初始化的多维字符串数组。注意,deepEquals() 返回 true,因为它执行了适当的比较,而普通的 equals() 错误地返回 false。如果我们更改数组中的一个元素,deepEquals() 将检测它。

流和数组

stream() 方法很容易从某些类型的数组中生成元素流。

import java.util.*;public class StreamFromArray {public static void main(String[] args) {String[] s = new Rand.String().array(10);Arrays.stream(s).skip(3).limit(5).map(ss -> ss + "!").forEach(System.out::println);int[] ia = new Rand.Pint().array(10);Arrays.stream(ia).skip(3).limit(5).map(i -> i * 10).forEach(System.out::println);Arrays.stream(new long[10]);Arrays.stream(new double[10]);// Only int, long and double work:// - Arrays.stream(new boolean[10]);// - Arrays.stream(new byte[10]);// - Arrays.stream(new char[10]);// - Arrays.stream(new short[10]);// - Arrays.stream(new float[10]);// For the other types you must use wrapped arrays:float[] fa = new Rand.Pfloat().array(10);Arrays.stream(ConvertTo.boxed(fa));Arrays.stream(new Rand.Float().array(10));}
}

在这里插入图片描述

只有“原生类型” intlongdouble 可以与 Arrays.stream() 一起使用;对于其他的,您必须以某种方式获得一个包装类型的数组。

通常,将数组转换为流来生成所需的结果要比直接操作数组容易得多。请注意,即使流已经“用完”(您不能重复使用它),您仍然拥有该数组,因此您可以以其他方式使用它----包括生成另一个流。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vivado产生报告阅读分析17-时序报告13

CDC 拓扑结构的简化板级原理图 以下部分展示了 CDC 拓扑结构的简化板级原理图以及简要说明。在所有板级原理图中 &#xff0c; 源时钟信号线 &#xff08; 通常为 clk_a&#xff09; 以蓝色高亮 &#xff0c; 目标时钟信号线 &#xff08; 通常为 clk_b &#xff09; 以橙色…

Leaflet结合Echarts实现迁徙图

效果图如下&#xff1a; <!DOCTYPE html> <html><head><title>Leaflet结合Echarts4实现迁徙图</title><meta charset"utf-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0">…

虚拟机VMware上安装Ubuntu系统(详细图文教程)

关于虚拟机VMware的安装教程&#xff0c;学者看我另外一篇博客&#xff1a;VMware详细安装教程 目录 一、Ubuntn系统准备二、VMware上安装Ubuntn系统2.1 答疑 三、导入Ubuntu系统四、总结 一、Ubuntn系统准备 先下载好Ubuntn系统&#xff0c;这里我提供一个&#xff0c;下载链…

蓝桥杯物联网竞赛_STM32L071_2_继电器控制

CubeMX配置&#xff1a; Function.c及Function.h&#xff1a; #include "Function.h" #include "gpio.h" void Function_LD5_ON(void){HAL_GPIO_WritePin(LD5_GPIO_Port, LD5_Pin, GPIO_PIN_RESET); }void Function_LD5_OFF(void){HAL_GPIO_WritePin(LD5_…

如何使用Fiddler进行弱网测试

测试APP、web经常需要用到弱网测试&#xff0c;也就是在信号差、网络慢的情况下进行测试。我们自己平常在使用手机APP时&#xff0c;在地铁、电梯、车库等场景经常会遇到会话中断、超时等情况&#xff0c;这种就属于弱网。 普通的弱网测试可以选择第三方工具对带宽、丢包、延时…

DAOS低时延与高性能RDMA网络

什么是RDMA RDMA&#xff08;Remote Direct Memory Access&#xff09;远程直接内存访问是一种技术&#xff0c;它使两台联网的计算机能够在主内存中交换数据&#xff0c;而无需依赖任何一台计算机的处理器、缓存或操作系统。与基于本地的直接内存访问 ( DMA ) 一样&#xff0c…

使用 PowerShell 中的命令来删除共享目录

Remove-SmbShare -Name "ShareName" 请将 "ShareName" 替换为您要删除的实际共享目录的名称。 请注意&#xff0c;执行此命令需要具有适当的权限。确保您以管理员身份运行 PowerShell 或具有足够的权限来删除共享目录。

AMESim|学习记录

此文记录AMESim学习过程中的各种情况。 目录 01 王佳. AUV 浮力调节系统设计及控制策略研究[D]. 天津大学, 2017.01 王佳. AUV 浮力调节系统设计及控制策略研究[D]. 天津大学, 2017. 01 王佳. AUV 浮力调节系统设计及控制策略研究[D]. 天津大学, 2017. 开始步入正文 01 王佳.…

SQLite3 数据库学习(六):Qt 嵌入式 Web 服务器详解

参考引用 SQLite 权威指南&#xff08;第二版&#xff09;SQLite3 入门 1. Apache 搭建 cgi 环境 1.1 什么是 Apache Apache 是世界使用排名第一的 Web 服务器软件 它可以运行在几乎所有广泛使用的计算机平台上&#xff0c;由于其跨平台和安全性被广泛使用 1.2 具体搭建流程…

如何使用 Python+selenium 进行 web 自动化测试?

Selenium是一个自动化测试工具&#xff0c;它可以模拟用户在浏览器中的操作&#xff0c;比如点击、输入、选择等等。它支持多种浏览器&#xff0c;包括Chrome、Firefox、Safari等等&#xff0c;并且可以在多个平台上运行。 安装和配置Selenium 在使用Selenium之前&#xff0c…

Android组件化搭建学习

什么是组件化&#xff1f; 为什么要用组件化&#xff1f;在项目的开发过程中&#xff0c;随着开发人员的增多及功能的增加&#xff0c;如果提前没有使用合理的开发架构&#xff0c;那么代码会越来臃肿&#xff0c;功能间代码耦合也会越来越严重&#xff0c;这时候为了保证项目…