diff --git a/sources/tech/20191022 Initializing arrays in Java.md b/sources/tech/20191022 Initializing arrays in Java.md deleted file mode 100644 index 7971ec104b..0000000000 --- a/sources/tech/20191022 Initializing arrays in Java.md +++ /dev/null @@ -1,389 +0,0 @@ -[#]: collector: (lujun9972) -[#]: translator: (laingke) -[#]: reviewer: ( ) -[#]: publisher: ( ) -[#]: url: ( ) -[#]: subject: (Initializing arrays in Java) -[#]: via: (https://opensource.com/article/19/10/initializing-arrays-java) -[#]: author: (Chris Hermansen https://opensource.com/users/clhermansen) - -Initializing arrays in Java -====== -Arrays are a helpful data type for managing collections elements best -modeled in contiguous memory locations. Here's how to use them -effectively. -![Coffee beans and a cup of coffee][1] - -People who have experience programming in languages like C or FORTRAN are familiar with the concept of arrays. They’re basically a contiguous block of memory where each location is a certain type: integers, floating-point numbers, or what-have-you. - -The situation in Java is similar, but with a few extra wrinkles. - -### An example array - -Let’s make an array of 10 integers in Java: - - -``` -int[] ia = new int[10]; -``` - -What’s going on in the above piece of code? From left to right: - - 1. The **int[]** to the extreme left declares the _type_ of the variable as an array (denoted by the **[]**) of **int**. - - 2. To the right is the _name_ of the variable, which in this case is **ia**. - - 3. Next, the **=** tells us that the variable defined on the left side is set to what’s to the right side. - - 4. To the right of the **=** we see the word **new**, which in Java indicates that an object is being _initialized_, meaning that storage is allocated and its constructor is called ([see here for more information][2]). - - 5. Next, we see **int[10]**, which tells us that the specific object being initialized is an array of 10 integers. - - - - -Since Java is strongly-typed, the type of the variable **ia** must be compatible with the type of the expression on the right-hand side of the **=**. - -### Initializing the example array - -Let’s put this simple array in a piece of code and try it out. Save the following in a file called **Test1.java**, use **javac** to compile it, and use **java** to run it (in the terminal of course): - - -``` -import java.lang.*; - -public class Test1 { - -    public static void main([String][3][] args) { -        int[] ia = new int[10];                              // See note 1 below -        [System][4].out.println("ia is " + ia.getClass());        // See note 2 below -        for (int i = 0; i < ia.length; i++)                  // See note 3 below -            [System][4].out.println("ia[" + i + "] = " + ia[i]);  // See note 4 below -    } - -} -``` - -Let’s work through the most important bits. - - 1. Our declaration and initialization of the array of 10 integers, **ia**, is easy to spot. - 2. In the line just following, we see the expression **ia.getClass()**. That’s right, **ia** is an _object_ belonging to a _class_, and this code will let us know which class that is. - 3. In the next line following that, we see the start of the loop **for (int i = 0; i < ia.length; i++)**, which defines a loop index variable **i** that runs through a sequence from zero to one less than **ia.length**, which is an expression that tells us how many elements are defined in the array **ia**. - 4. Next, the body of the loop prints out the values of each element of **ia**. - - - -When this program is compiled and run, it produces the following results: - - -``` -me@mydesktop:~/Java$ javac Test1.java -me@mydesktop:~/Java$ java Test1 -ia is class [I -ia[0] = 0 -ia[1] = 0 -ia[2] = 0 -ia[3] = 0 -ia[4] = 0 -ia[5] = 0 -ia[6] = 0 -ia[7] = 0 -ia[8] = 0 -ia[9] = 0 -me@mydesktop:~/Java$ -``` - -The string representation of the output of **ia.getClass()** is **[I**, which is shorthand for "array of integer." Similar to the C programming language, Java arrays begin with element zero and extend up to element **<array size> – 1**. We can see above that each of the elements of **ia** are set to zero (by the array constructor, it seems). - -So, is that it? We declare the type, use the appropriate initializer, and we’re done? - -Well, no. There are many other ways to initialize an array in Java.  - -### Why do I want to initialize an array, anyway? - -The answer to this question, like that of all good questions, is "it depends." In this case, the answer depends on what we expect to do with the array once it is initialized. - -In some cases, arrays emerge naturally as a type of accumulator. For example, suppose we are writing code for counting the number of calls received and made by a set of telephone extensions in a small office. There are eight extensions, numbered one through eight, plus the operator’s extension, numbered zero. So we might declare two arrays: - - -``` -int[] callsMade; -int[] callsReceived; -``` - -Then, whenever we start a new period of accumulating call statistics, we initialize each array as: - - -``` -callsMade = new int[9]; -callsReceived = new int[9]; -``` - -At the end of each period of accumulating call statistics, we can print out the stats. In very rough terms, we might see: - - -``` -import java.lang.*; -import java.io.*; - -public class Test2 { - -    public static void main([String][3][] args) { - -        int[] callsMade; -        int[] callsReceived; - -        // initialize call counters - -        callsMade = new int[9]; -        callsReceived = new int[9]; - -        // process calls... -        //   an extension makes a call: callsMade[ext]++ -        //   an extension receives a call: callsReceived[ext]++ - -        // summarize call statistics - -        [System][4].out.printf("%3s%25s%25s\n","ext"," calls made", -            "calls received"); -        for (int ext = 0; ext < callsMade.length; ext++) -            [System][4].out.printf("%3d%25d%25d\n",ext, -                callsMade[ext],callsReceived[ext]); - -    } - -} -``` - -Which would produce output something like this: - - -``` -me@mydesktop:~/Java$ javac Test2.java -me@mydesktop:~/Java$ java Test2 -ext               calls made           calls received -  0                        0                        0 -  1                        0                        0 -  2                        0                        0 -  3                        0                        0 -  4                        0                        0 -  5                        0                        0 -  6                        0                        0 -  7                        0                        0 -  8                        0                        0 -me@mydesktop:~/Java$ -``` - -Not a very busy day in the call center. - -In the above example of an accumulator, we see that the starting value of zero as set by the array initializer is satisfactory for our needs. But in other cases, this starting value may not be the right choice. - -For example, in some kinds of geometric computations, we might need to initialize a two-dimensional array to the identity matrix (all zeros except for the ones along the main diagonal). We might choose to do this as: - - -``` - double[][] m = new double[3][3]; -        for (int d = 0; d < 3; d++) -            m[d][d] = 1.0; -``` - -In this case, we rely on the array initializer **new double[3][3]** to set the array to zeros, and then use a loop to set the diagonal elements to ones. In this simple case, we might use a shortcut that Java provides: - - -``` - double[][] m = { -         {1.0, 0.0, 0.0}, -         {0.0, 1.0, 0.0}, -         {0.0, 0.0, 1.0}}; -``` - -This type of visual structure is particularly appropriate in this sort of application, where it can be a useful double-check to see the actual layout of the array. But in the case where the number of rows and columns is only determined at run time, we might instead see something like this: - - -``` - int nrc; - // some code determines the number of rows & columns = nrc - double[][] m = new double[nrc][nrc]; - for (int d = 0; d < nrc; d++) -     m[d][d] = 1.0; -``` - -It’s worth mentioning that a two-dimensional array in Java is actually an array of arrays, and there’s nothing stopping the intrepid programmer from having each one of those second-level arrays be a different length. That is, something like this is completely legitimate: - - -``` -int [][] differentLengthRows = { -     { 1, 2, 3, 4, 5}, -     { 6, 7, 8, 9}, -     {10,11,12}, -     {13,14}, -     {15}}; -``` - -There are various linear algebra applications that involve irregularly-shaped matrices, where this type of structure could be applied (for more information see [this Wikipedia article][5] as a starting point). Beyond that, now that we understand that a two-dimensional array is actually an array of arrays, it shouldn’t be too much of a surprise that: - - -``` -differentLengthRows.length -``` - -tells us the number of rows in the two-dimensional array **differentLengthRows**, and: - - -``` -differentLengthRows[i].length -``` - -tells us the number of columns in row **i** of **differentLengthRows**. - -### Taking the array further - -Considering this idea of array size that is determined at run time, we see that arrays still require us to know that size before instantiating them. But what if we don’t know the size until we’ve processed all of the data? Does that mean we have to process it once to figure out the size of the array, and then process it again? That could be hard to do, especially if we only get one chance to consume the data. - -The [Java Collections Framework][6] solves this problem in a nice way. One of the things provided there is the class **ArrayList**, which is like an array but dynamically extensible. To demonstrate the workings of **ArrayList**, let’s create one and initialize it to the first 20 [Fibonacci numbers][7]: - - -``` -import java.lang.*; -import java.util.*; - -public class Test3 { -        -        public static void main([String][3][] args) { - -                ArrayList<Integer> fibos = new ArrayList<Integer>(); - -                fibos.add(0); -                fibos.add(1); -                for (int i = 2; i < 20; i++) -                        fibos.add(fibos.get(i-1) + fibos.get(i-2)); - -                for (int i = 0; i < fibos.size(); i++) -                        [System][4].out.println("fibonacci " + i + -                       " = " + fibos.get(i)); - -        } -} -``` - -Above, we see: - - * The declaration and instantiation of an **ArrayList** that is used to store **Integer**s. - * The use of **add()** to append to the **ArrayList** instance. - * The use of **get()** to retrieve an element by index number. - * The use of **size()** to determine how many elements are already in the **ArrayList** instance. - - - -Not shown is the **put()** method, which places a value at a given index number. - -The output of this program is: - - -``` -fibonacci 0 = 0 -fibonacci 1 = 1 -fibonacci 2 = 1 -fibonacci 3 = 2 -fibonacci 4 = 3 -fibonacci 5 = 5 -fibonacci 6 = 8 -fibonacci 7 = 13 -fibonacci 8 = 21 -fibonacci 9 = 34 -fibonacci 10 = 55 -fibonacci 11 = 89 -fibonacci 12 = 144 -fibonacci 13 = 233 -fibonacci 14 = 377 -fibonacci 15 = 610 -fibonacci 16 = 987 -fibonacci 17 = 1597 -fibonacci 18 = 2584 -fibonacci 19 = 4181 -``` - -**ArrayList** instances can also be initialized by other techniques. For example, an array can be supplied to the **ArrayList** constructor, or the **List.of()** and **Arrays.asList()** methods can be used when the initial elements are known at compile time. I don’t find myself using these options all that often since my primary use case for an **ArrayList** is when I only want to read the data once. - -Moreover, an **ArrayList** instance can be converted to an array using its **toArray()** method, for those who prefer to work with an array once the data is loaded; or, returning to the current topic, once the **ArrayList** instance is initialized. - -The Java Collections Framework provides another kind of array-like data structure called a **Map**. What I mean by "array-like" is that a **Map** defines a collection of objects whose values can be set or retrieved by a key, but unlike an array (or an **ArrayList**), this key need not be an integer; it could be a **String** or any other complex object. - -For example, we can create a **Map** whose keys are **String**s and whose values are **Integer**s as follows: - - -``` -Map<[String][3],Integer> stoi = new Map<[String][3],Integer>(); -``` - -Then we can initialize this **Map** as follows: - - -``` -stoi.set("one",1); -stoi.set("two",2); -stoi.set("three",3); -``` - -And so on. Later, when we want to know the numeric value of **"three"**, we can retrieve it as: - - -``` -stoi.get("three"); -``` - -In my world, a **Map** is useful for converting strings occurring in third-party datasets into coherent code values in my datasets. As a part of a [data transformation pipeline][8], I will often build a small standalone program to clean the data before processing it; for this, I will almost always use one or more **Map**s. - -Worth mentioning is that it’s quite possible, and sometimes reasonable, to have **ArrayLists** of **ArrayLists** and **Map**s of **Map**s. For example, let’s assume we’re looking at trees, and we’re interested in accumulating the count of the number of trees by tree species and age range. Assuming that the age range definition is a set of string values ("young," "mid," "mature," and "old") and that the species are string values like "Douglas fir," "western red cedar," and so forth, then we might define a **Map** of **Map**s as: - - -``` -Map<[String][3],Map<[String][3],Integer>> counter = -        new Map<[String][3],Map<[String][3],Integer>>(); -``` - -One thing to watch out for here is that the above only creates storage for the _rows_ of **Map**s. So, our accumulation code might look like: - - -``` -// assume at this point we have figured out the species -// and age range -if (!counter.containsKey(species)) -        counter.put(species,new Map<[String][3],Integer>()); -if (!counter.get(species).containsKey(ageRange)) -        counter.get(species).put(ageRange,0); -``` - -At which point, we can start accumulating as: - - -``` -counter.get(species).put(ageRange, -        counter.get(species).get(ageRange) + 1); -``` - -Finally, it’s worth mentioning that the (new in Java 8) Streams facility can also be used to initialize arrays, **ArrayList** instances, and **Map** instances. A nice discussion of this feature can be found [here][9] and [here][10]. - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/19/10/initializing-arrays-java - -作者:[Chris Hermansen][a] -选题:[lujun9972][b] -译者:[laingke](https://github.com/laingke) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://opensource.com/users/clhermansen -[b]: https://github.com/lujun9972 -[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/java-coffee-mug.jpg?itok=Bj6rQo8r (Coffee beans and a cup of coffee) -[2]: https://opensource.com/article/19/8/what-object-java -[3]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string -[4]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+system -[5]: https://en.wikipedia.org/wiki/Irregular_matrix -[6]: https://en.wikipedia.org/wiki/Java_collections_framework -[7]: https://en.wikipedia.org/wiki/Fibonacci_number -[8]: https://towardsdatascience.com/data-science-for-startups-data-pipelines-786f6746a59a -[9]: https://stackoverflow.com/questions/36885371/lambda-expression-to-initialize-array -[10]: https://stackoverflow.com/questions/32868665/how-to-initialize-a-map-using-a-lambda diff --git a/translated/tech/20191022 Initializing arrays in Java.md b/translated/tech/20191022 Initializing arrays in Java.md new file mode 100644 index 0000000000..839346336e --- /dev/null +++ b/translated/tech/20191022 Initializing arrays in Java.md @@ -0,0 +1,378 @@ +[#]: collector: (lujun9972) +[#]: translator: (laingke) +[#]: reviewer: ( ) +[#]: publisher: ( ) +[#]: url: ( ) +[#]: subject: (Initializing arrays in Java) +[#]: via: (https://opensource.com/article/19/10/initializing-arrays-java) +[#]: author: (Chris Hermansen https://opensource.com/users/clhermansen) + +Java 中初始化数组 +====== +数组是一种有用的数据类型,用于管理在连续内存位置中建模最好的集合元素。下面是如何有效地使用它们。 +![Coffee beans and a cup of coffee][1] + +有使用 C 或者 FORTRAN 语言编程经验的人会对数组的概念很熟悉。它们基本上是一个连续的内存块,其中每个位置都是某种数据类型:整型、浮点型或者诸如此类的数据类型。 + +Java 的情况与此类似,但是有一些额外的问题。 + +### 一个数组的示例 + +让我们在 Java 中创建一个长度为 10 的整型数组: + + +``` +int[] ia = new int[10]; +``` + +上面的代码片段会发生什么?从左到右依次是: + + 1. 最左边的 **int[]** 将数组变量的 _类型_ 声明为 **int**(由 **[]**表示)。 + + 2. 它的右边是变量的名称,当前为 **ia**。 + + 3. 接下来,**=** 告诉我们,左侧定义的变量赋值为右侧的内容。 + + 4. 在 **=** 的右侧,我们看到了 **new**,它在 Java 中表示一个对象正在 _被初始化_ 中,这意味着已为其分配存储空间并调用了其构造函数([请参见此处以获取更多信息][2])。 + + 5. 然后,我们看到 **int[10]**,它告诉我们正在初始化的这个对象是包含 10 个整型的数组。 + + +因为 Java 是强类型的,所以变量 **ia** 的类型必须跟 **=** 右侧表达式的类型兼容。 + +### 初始化示例数组 + +让我们把这个简单的数组放在一段代码中,并尝试运行一下。将以下内容保存到一个名为 **Test1.java** 的文件中,使用 **javac** 编译,使用 **java** 运行(当然是在终端中): + +``` +import java.lang.*; + +public class Test1 { + + public static void main(String[] args) { + int[] ia = new int[10]; // 见下文注 1 + System.out.println("ia is " + ia.getClass()); // 见下文注 2 + for (int i = 0; i < ia.length; i++) // 见下文注 3 + System.out.println("ia[" + i + "] = " + ia[i]); // 见下文注 4 + } + +} +``` + +让我们来看看最重要的部分。 + + 1. 我们很容易发现长度为 10 的整型数组,**ia** 的声明和初始化。 + 2. 在下面的行中,我们看到表达式 **ia.getClass()**。没错,**ia** 是属于一个 _类_ 的 _对象_,这行代码将告诉我们是哪个类。 + 3. 在紧接的下一行中,我们看到了一个循环 **for (int i = 0; i < ia.length; i++)**,它定义了一个循环索引变量 **i**,该变量运行的序列从 0 到比 **ia.length** 小 1,这个表达式告诉我们在数组 **ia** 中定义了多少个元素。 + 4. 接下来,循环体打印出 **ia** 的每个元素的值。 + + + +当这个程序被编译和运行时,它产生以下结果: + + +``` +me@mydesktop:~/Java$ javac Test1.java +me@mydesktop:~/Java$ java Test1 +ia is class [I +ia[0] = 0 +ia[1] = 0 +ia[2] = 0 +ia[3] = 0 +ia[4] = 0 +ia[5] = 0 +ia[6] = 0 +ia[7] = 0 +ia[8] = 0 +ia[9] = 0 +me@mydesktop:~/Java$ +``` + +**ia.getClass()** 的输出的字符串表示形式是 **[I**,它是“整数数组”的简写。与 C 语言类似,Java 数组以第 0 个元素开始,扩展到第 **<数组大小> - 1** 个元素。我们可以在上面看到数组 ia 的每个元素都设置为零(看来是数组构造函数)。 + +所以,就这些吗?声明类型,使用适当的初始化器,就完成了吗? + +好吧,并没有。在 Java 中有许多其它方法来初始化数组。 + +### 为什么我要初始化一个数组,有其它方式吗? + +像所有好的问题一样,这个问题的答案是“视情况而定”。在这种情况下,答案取决于初始化后我们希望对数组做什么。 + +在某些情况下,数组自然会作为一种累加器出现。例如,假设我们正在编程实现计算小型办公室中一组电话分机接收和拨打的电话数量。一共有 8 个分机,编号为 1 到 8,加上话务员的分机,编号为 0。 因此,我们可以声明两个数组: + +``` +int[] callsMade; +int[] callsReceived; +``` + +然后,每当我们开始一个新的累积呼叫统计数据的周期时,我们就将每个数组初始化为: + +``` +callsMade = new int[9]; +callsReceived = new int[9]; +``` + +在每个累积通话统计数据的最后阶段,我们可以打印出统计数据。粗略地说,我们可能会看到: + + +``` +import java.lang.*; +import java.io.*; + +public class Test2 { + + public static void main(String[] args) { + + int[] callsMade; + int[] callsReceived; + + // 初始化呼叫计数器 + + callsMade = new int[9]; + callsReceived = new int[9]; + + // 处理呼叫…… + // 分机拨打电话:callsMade[ext]++ + // 分机接听电话:callsReceived[ext]++ + + // 汇总通话统计 + + System.out.printf("%3s%25s%25s\n", "ext", " calls made", + "calls received"); + for (int ext = 0; ext < callsMade.length; ext++) { + System.out.printf("%3d%25d%25d\n", ext, + callsMade[ext], callsReceived[ext]); + } + + } + +} +``` + +这会产生这样的输出: + + +``` +me@mydesktop:~/Java$ javac Test2.java +me@mydesktop:~/Java$ java Test2 +ext calls made calls received + 0 0 0 + 1 0 0 + 2 0 0 + 3 0 0 + 4 0 0 + 5 0 0 + 6 0 0 + 7 0 0 + 8 0 0 +me@mydesktop:~/Java$ +``` + +呼叫中心不是很忙的一天。 + +在上面的累加器示例中,我们看到由数组初始化程序设置的零起始值可以满足我们的需求。但是在其它情况下,这个起始值可能不是正确的选择。 + +例如,在某些几何计算中,我们可能需要将二维数组初始化为单位矩阵(除沿主对角线的那些零以外的所有零)。我们可以选择这样做: + + +``` +double[][] m = new double[3][3]; +for (int d = 0; d < 3; d++) { + m[d][d] = 1.0; +} +``` + +在这种情况下,我们依靠数组初始化器 **new double[3][3]** 将数组设置为零,然后使用循环将对角元素设置为 1。 在这种简单情况下,我们可以使用 Java 提供的快捷方式: + +``` +double[][] m = { + {1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0}}; +``` + +这种可视结构特别适用于这种应用程序,在这种应用程序中,可以通过双重检查查看数组的实际布局。但是在这种情况下,行数和列数只在运行时确定,我们可能会看到这样的东西: + +``` +int nrc; +// 一些代码确定行数和列数 = nrc +double[][] m = new double[nrc][nrc]; +for (int d = 0; d < nrc; d++) { + m[d][d] = 1.0; +} +``` + +值得一提的是,Java 中的二维数组实际上是数组的数组,没有什么能阻止无畏的程序员让这些第二级数组中的每个数组的长度都不同。也就是说,下面这样的事情是完全合法的: + + +``` +int [][] differentLengthRows = { + {1, 2, 3, 4, 5}, + {6, 7, 8, 9}, + {10, 11, 12}, + {13, 14}, + {15}}; +``` + +在涉及不规则形状矩阵的各种线性代数应用中,可以应用这种类型的结构(有关更多信息,请参见[此 Wikipedia 文章][5])。除此之外,既然我们了解到二维数组实际上是数组的数组,那么以下内容也就不足为奇了: + +``` +differentLengthRows.length +``` + +告诉我们二维数组 **differentLengthRows** 的行数,并且: + +``` +differentLengthRows[i].length +``` + +告诉我们 **differentLengthRows** 第 **i** 行的列数。 + +### 深入理解数组 + +考虑到在运行时确定数组大小的想法,我们看到数组在实例化之前仍需要我们知道该大小。但是,如果在处理完所有数据之前我们不知道大小怎么办?这是否意味着我们必须先处理一次以找出数组的大小,然后再次处理?这可能很难做到,尤其是如果我们只有一次机会使用数据时。 + +[Java 集合框架][6]很好地解决了这个问题。提供的其中一项是 **ArrayList** 类,它类似于数组,但可以动态扩展。为了演示 **ArrayList** 的工作原理,让我们创建一个 ArrayList 并将其初始化为前 20 个[斐波那契数字][7]: + +``` +import java.lang.*; +import java.util.*; + +public class Test3 { + + public static void main(String[] args) { + + ArrayList fibos = new ArrayList(); + + fibos.add(0); + fibos.add(1); + for (int i = 2; i < 20; i++) { + fibos.add(fibos.get(i - 1) + fibos.get(i - 2)); + } + + for (int i = 0; i < fibos.size(); i++) { + System.out.println("fibonacci " + i + " = " + fibos.get(i)); + } + + } +} +``` + +上面的代码中,我们看到: + + * 用于存储多个 **Integer** 的 **ArrayList** 的声明和实例化。 + * 使用 **add()** 附加到 **ArrayList** 实例。 + * 使用 **get()** 通过索引号检索元素。 + * 使用 **size()** 来确定 **ArrayList** 实例中已经有多少个元素。 + + + +没有显示 **put()** 方法,它的作用是将一个值放在给定的索引号上。 + +该程序的输出为: + + +``` +fibonacci 0 = 0 +fibonacci 1 = 1 +fibonacci 2 = 1 +fibonacci 3 = 2 +fibonacci 4 = 3 +fibonacci 5 = 5 +fibonacci 6 = 8 +fibonacci 7 = 13 +fibonacci 8 = 21 +fibonacci 9 = 34 +fibonacci 10 = 55 +fibonacci 11 = 89 +fibonacci 12 = 144 +fibonacci 13 = 233 +fibonacci 14 = 377 +fibonacci 15 = 610 +fibonacci 16 = 987 +fibonacci 17 = 1597 +fibonacci 18 = 2584 +fibonacci 19 = 4181 +``` + +**ArrayList** 实例也可以通过其它方式初始化。例如,一个数组可以提供给 **ArrayList** 构造器,或者 **List.of()** 和 **array.aslist()** 方法可以在编译过程中知道初始元素时使用。我发现自己并不经常使用这些选项,因为我对 **ArrayList** 的主要用途是我只想读取一次数据。 + +此外,对于那些喜欢在加载数据后使用数组的人,可以使用 **ArrayList** 的 **toArray()** 方法将其实例转换为数组;或者,在初始化 **ArrayList** 实例之后,返回到当前数组本身。 + +Java 集合框架提供了另一种类似数组的数据结构,称为 **Map**。我所说的“类似数组”是指 **Map** 定义了一个对象集合,它的值可以通过一个键来设置或检索,但与数组(或 **ArrayList**)不同,这个键不需要是整型数;它可以是 **String** 或任何其它复杂对象。 + +例如,我们可以创建一个 **Map**,其键为 **String**,其值为 **Integer** 类型,如下: + +``` +Map stoi = new Map(); +``` + +然后我们可以对这个 **Map** 进行如下初始化: + + +``` +stoi.set("one",1); +stoi.set("two",2); +stoi.set("three",3); +``` + +等类似操作。稍后,当我们想要知道 **"three"** 的数值时,我们可以通过下面的方式将其检索出来: + + +``` +stoi.get("three"); +``` + +在我的认知中,**Map** 对于将第三方数据集中出现的字符串转换为我的数据集中的一致代码值非常有用。作为[数据转换管道][8]的一部分,我经常会构建一个小型的独立程序,用作在处理数据之前清理数据;为此,我几乎总是会使用一个或多个 **Map**。 + +值得一提的是,内部定义有 **ArrayList** 的 **ArrayLists** 和 **Map** 的 **Maps** 是很可能的,有时也是合理的。例如,假设我们在看树,我们对按树种和年龄范围累积树的数目感兴趣。假设年龄范围定义是一组字符串值(“young”、“mid”、“mature” 和 “old”),物种是 “Douglas fir”、“western red cedar” 等字符串值,那么我们可以将这个 **Map** 中的 **Map** 定义为: + +``` +Map> counter = new Map>(); +``` + +One thing to watch out for here is that the above only creates storage for the _rows_ of **Map**s. So, our accumulation code might look like: +这里需要注意的一件事是,以上内容仅为 **Map** 的 _行_ 创建存储。 因此,我们的累加代码可能类似于: + +``` +// 假设我们已经知道了物种和年龄范围 +if (!counter.containsKey(species)) { + counter.put(species,new Map()); +} +if (!counter.get(species).containsKey(ageRange)) { + counter.get(species).put(ageRange,0); +} +``` + +此时,我们可以开始累加: + + +``` +counter.get(species).put(ageRange, counter.get(species).get(ageRange) + 1); +``` + +最后,值得一提的是(Java 8 中的新特性)Streams 还可以用来初始化数组、**ArrayList** 实例和 **Map** 实例。关于此特性的详细讨论可以在[此处][9]和[此处][10]中找到。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/19/10/initializing-arrays-java + +作者:[Chris Hermansen][a] +选题:[lujun9972][b] +译者:[laingke](https://github.com/laingke) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://opensource.com/users/clhermansen +[b]: https://github.com/lujun9972 +[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/java-coffee-mug.jpg?itok=Bj6rQo8r (Coffee beans and a cup of coffee) +[2]: https://opensource.com/article/19/8/what-object-java +[3]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string +[4]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+system +[5]: https://en.wikipedia.org/wiki/Irregular_matrix +[6]: https://en.wikipedia.org/wiki/Java_collections_framework +[7]: https://en.wikipedia.org/wiki/Fibonacci_number +[8]: https://towardsdatascience.com/data-science-for-startups-data-pipelines-786f6746a59a +[9]: https://stackoverflow.com/questions/36885371/lambda-expression-to-initialize-array +[10]: https://stackoverflow.com/questions/32868665/how-to-initialize-a-map-using-a-lambda