الفئة المساعدة Arrays
في هذا الدرس 11 موضوعات
هذا الدرس متاح حاليًا باللغة الإنجليزية فقط، ولم تُنشر نسخته العربية بعد.
Lesson Overview
By now you have written a loop to print an array, a loop to find the largest element, and perhaps a loop to copy. Java ships ready-made versions of these chores in one place: the java.util.Arrays class, a toolbox full of static helper methods for arrays.
In locker terms: instead of walking along the row yourself every time, you call a caretaker who can read the whole row out loud (toString), put the lockers in order (sort), fill them all with the same item (fill), build you a duplicate row (copyOf), and tell you whether two rows hold the same things (equals).
This lesson also fixes two debts from earlier: Lesson 1 said "a real copy comes later", and printing an array with println(arr) gives a strange code instead of the values.
Why this matters: knowing the standard helper beats rewriting it. Tested library code is shorter, clearer, and less likely to hide an off-by-one error than your own loop.
This lesson builds on arrays (Lessons 1-3) and on references (BEG-009).
Learning Objectives
By the end of this lesson you will be able to:
- Import
java.util.Arraysand call its static methods. - Print an array readably with
Arrays.toString, and a 2D array withArrays.deepToString. - Sort an array in place with
Arrays.sort. - Make a real copy with
Arrays.copyOfandArrays.copyOfRange, including growing or shrinking. - Fill an array with one value, and compare two arrays by content with
Arrays.equals. - Explain why
b = aanda == bdo not copy and do not compare contents. - Explain why a copy of a 2D array needs one more step.
Written Explanation
Import first
Arrays lives in the package java.util, so the file starts with:
import java.util.Arrays;All its methods are static: you call them on the class, as in Arrays.sort(a), not on an array object.
Printing: toString
System.out.println(a) for an array prints the type and a hash code, such as [I@6d06d69c, because an array does not define a readable text form of its own. The text and number after @ are not useful. Use:
System.out.println(Arrays.toString(a)); // [3, 1, 2]For a 2D array, toString would show the inner arrays as codes too, because the elements are arrays. Arrays.deepToString(grid) goes into the nested arrays and prints [[1, 2], [3, 4]].
Sorting: sort
Arrays.sort(a) rearranges a in place into ascending order. For int[] the order is numeric; for String[] it is alphabetical by character code, so all upper-case letters come before lower-case ones, which surprises many beginners. The method returns nothing (void), so the original order is lost. If you still need it, sort a copy. An overload Arrays.sort(a, from, to) sorts only the positions from from up to, but not including, to, and throws an exception when the range is invalid.
Copying: copyOf and copyOfRange
int[] c = Arrays.copyOf(a, a.length); // same size
int[] bigger = Arrays.copyOf(a, 5); // longer: extra slots are 0
int[] smaller = Arrays.copyOf(a, 2); // shorter: cut off the end
int[] part = Arrays.copyOfRange(a, 1, 3); // positions 1 and 2 (end excluded)The result is a new array. When it is longer, the new slots hold the default value (0, false, or null). This is also how you "grow" an array: create a larger copy and assign it to your variable. copyOfRange again includes the start and excludes the end, as substring does.
Filling: fill
Arrays.fill(a, 7) sets every element to 7. It is shorter than a loop and clearly states the intent, for example to mark every seat as free or to start every counter at -1.
Comparing: equals
Two array variables compared with == ask "are they the same array object?". Calling a.equals(b) on an array does the same, because arrays do not override it. To ask "do they hold the same values in the same order?", use:
Arrays.equals(x, y) // compares length and every elementFor nested arrays there is Arrays.deepEquals.
Copies of copies: 2D arrays are shallow
A 2D array is an array of row pointers (Lesson 3). Arrays.copyOf(grid, grid.length) copies the outer row of pointers; the inner rows are still shared by the original and the copy. A change to copy[0][0] therefore also changes grid[0][0]. For an independent copy, copy every row too:
int[][] deep = new int[grid.length][];
for (int r = 0; r < grid.length; r++) {
deep[r] = Arrays.copyOf(grid[r], grid[r].length);
}The same caution applies to an array of any other reference type: the copy holds the same objects (for String, which is immutable, that is harmless).
Examples
Example 1: print, sort, copy, fill (simple)
import java.util.Arrays;
public class Ex1 {
public static void main(String[] args) {
int[] a = {3, 1, 2};
System.out.println(Arrays.toString(a));
Arrays.sort(a);
System.out.println(Arrays.toString(a));
int[] b = a;
int[] c = Arrays.copyOf(a, a.length);
b[0] = 100;
System.out.println(a[0] + " " + c[0]);
int[] zeros = new int[4];
Arrays.fill(zeros, 7);
System.out.println(Arrays.toString(zeros));
System.out.println(Arrays.toString(Arrays.copyOf(a, 5)));
System.out.println(Arrays.toString(Arrays.copyOf(a, 2)));
System.out.println(Arrays.toString(Arrays.copyOfRange(zeros, 1, 3)));
String[] words = {"pear", "apple", "fig"};
Arrays.sort(words);
System.out.println(Arrays.toString(words));
}
}Output (compiled and run with JDK 21):
[3, 1, 2]
[1, 2, 3]
100 1
[7, 7, 7, 7]
[100, 2, 3, 0, 0]
[100, 2]
[7, 7]
[apple, fig, pear]Writing b[0] = 100 changed a[0] (same array) but not c[0] (the real copy). copyOf(a, 5) padded with zeros and copyOf(a, 2) cut the array short. The words came out alphabetical.
Example 2: comparing arrays and sorting a copy (practical)
import java.util.Arrays;
public class Ex2 {
public static void main(String[] args) {
int[] x = {1, 2, 3};
int[] y = {1, 2, 3};
System.out.println(x == y);
System.out.println(x.equals(y));
System.out.println(Arrays.equals(x, y));
int[] original = {5, 9, 1, 7};
int[] sorted = Arrays.copyOf(original, original.length);
Arrays.sort(sorted);
System.out.println("smallest " + sorted[0] + ", largest " + sorted[sorted.length - 1]);
System.out.println(Arrays.toString(original));
System.out.println(original.toString().startsWith("[I@"));
}
}Output:
false
false
true
smallest 1, largest 9
[5, 9, 1, 7]
trueThe arrays x and y hold the same numbers but are two different objects, so == and .equals say false, and only Arrays.equals says true. After sorting a copy, the smallest and largest come from the two ends, and the original order is intact. The last line confirms that an array's own toString() begins with the type code [I@.
Example 3: shallow and deep copies of a grid (realistic)
import java.util.Arrays;
public class Ex3 {
public static void main(String[] args) {
int[][] grid = {{1, 2}, {3, 4}};
System.out.println(Arrays.toString(grid).startsWith("[[I@"));
System.out.println(Arrays.deepToString(grid));
int[][] shallow = Arrays.copyOf(grid, grid.length);
shallow[0][0] = 99;
System.out.println(grid[0][0]);
int[][] deep = new int[grid.length][];
for (int r = 0; r < grid.length; r++) {
deep[r] = Arrays.copyOf(grid[r], grid[r].length);
}
deep[1][1] = -1;
System.out.println(Arrays.deepToString(grid));
System.out.println(Arrays.deepToString(deep));
int[] data = {4, 2};
Arrays.sort(data, 0, 3);
}
}Output (JDK-internal trace lines left out):
true
[[1, 2], [3, 4]]
99
[[99, 2], [3, 4]]
[[99, 2], [3, -1]]
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 3
at Ex3.main(Ex3.java:19)Arrays.toString on a grid prints row codes, deepToString prints the values. Changing the shallow copy changed the original (99), because the rows are shared. The deep copy has its own rows, so the later change to deep[1][1] left grid untouched, and the original still shows the earlier 99. The last line asks sort for a range ending at 3 in a length-2 array, which the method rejects with an ArrayIndexOutOfBoundsException.
Backend Insight
Real programs take arrays from callers they do not control. Two habits from this lesson matter in production:
- Defensive copies. If a method stores or returns an array that belongs to another part of the program, copy it. Otherwise a later change in one place silently changes the data in another.
Arrays.copyOfis the one-line way to do it. - Do not sort what you do not own.
Arrays.sortchanges the array it is given. Sorting a caller's array changes the caller's data. Sort a copy unless changing the order is the whole point of your method.
Searching and sorting data is a core part of backend work, and databases do it for you with ORDER BY. Sorting in Java is for data already in memory.
Common Mistakes
Mistake 1: Printing an array with println(a)
You get a code like [I@6d06d69c. Use Arrays.toString(a), or Arrays.deepToString(g) for a grid.
Mistake 2: Thinking b = a copies
It creates a second name for the same array. Use Arrays.copyOf for a copy.
Mistake 3: Comparing arrays with == or .equals
Both ask whether they are the same object. Use Arrays.equals(a, b) to compare contents.
Mistake 4: Expecting sort to return the sorted array
Arrays.sort(a); sorts a and returns nothing. Writing int[] s = Arrays.sort(a); does not compile.
Mistake 5: Believing a copy of a grid is independent
Arrays.copyOf on a 2D array shares the rows. Copy each row as well.
Mistake 6: Forgetting the import
Without import java.util.Arrays;, the compiler reports that it cannot find Arrays.
Exercises
Try each exercise yourself before opening the solutions.
Level A: Foundation
A1. Which statement prints [4, 8, 15] for int[] a = {4, 8, 15};: println(a) or println(Arrays.toString(a))?
أظهر الحل A1
A1. System.out.println(Arrays.toString(a)). The plain println(a) prints a type code and hash.
A2. What does Arrays.copyOf(new int[]{1, 2, 3}, 5) produce?
أظهر الحل A2
A2. [1, 2, 3, 0, 0]: the new longer array is padded with the default value for int.
A3. After int[] a = {9, 3, 6}; Arrays.sort(a);, what is a[0]?
أظهر الحل A3
A3. 3. The array becomes {3, 6, 9}.
Level B: Application
B1. You have int[] scores = {70, 90, 80} and need the highest value without changing the order of scores. Write the code using Arrays.
أظهر الحل B1
B1.
int[] copy = Arrays.copyOf(scores, scores.length);
Arrays.sort(copy);
int highest = copy[copy.length - 1];scores keeps its order because only the copy was sorted. (This assumes at least one element.)
B2. What do these print?
int[] p = {1, 2};
int[] q = {1, 2};
int[] r = p;
System.out.println((p == q) + " " + (p == r) + " " + Arrays.equals(p, q));أظهر الحل B2
B2. It prints false true true. p and q are different arrays with equal contents, p and r are the same array, and Arrays.equals compares contents.
B3. Use Arrays.fill and Arrays.copyOfRange to build {0, 0, 5, 5} from a 6-element array that you first fill with 5 (the answer is two statements after the fill).
أظهر الحل B3
B3.
int[] a = new int[6];
Arrays.fill(a, 5);
int[] b = Arrays.copyOfRange(a, 0, 4); // {5, 5, 5, 5}
b[0] = 0;
b[1] = 0; // {0, 0, 5, 5}Several equivalent solutions are possible; the point is that copyOfRange gives a new, independent array that you may change.
Level C: Challenge
C1. Write static int[] addOne(int[] a, int value) that returns a new array one element longer, with value at the end, leaving a unchanged. Use Arrays.
أظهر الحل C1
C1.
static int[] addOne(int[] a, int value) {
int[] result = Arrays.copyOf(a, a.length + 1);
result[result.length - 1] = value;
return result;
}The extra slot from copyOf is the new last position, and a is never touched.
C2. A method static int[][] copyGrid(int[][] g) must return an independent copy. Write it, and explain which line would be wrong if you replaced the loop body with deep[r] = g[r];.
أظهر الحل C2
C2.
static int[][] copyGrid(int[][] g) {
int[][] deep = new int[g.length][];
for (int r = 0; r < g.length; r++) {
deep[r] = Arrays.copyOf(g[r], g[r].length);
}
return deep;
}With deep[r] = g[r]; the rows would be shared with the original, so changing copy[0][0] would still change g[0][0]: the result would look like a copy but would not be independent.
Mini Challenge
Write a small "top three" program. Given an int[] of at least three scores (for example {62, 91, 75, 88, 49, 91}), print the three highest values from highest to lowest without changing the original array, and print the original array afterwards to prove it is unchanged. Use Arrays.copyOf, Arrays.sort, and Arrays.toString. What does your program do when the array has fewer than three elements?
Check your work: you sorted a copy, you indexed from length - 1 downwards, and you handled the short array instead of crashing.
Summary & Next Lesson
Key takeaways
Arraysis a toolbox of static helpers; importjava.util.Arraysfirst.Arrays.toString(anddeepToStringfor grids) prints readable contents;println(arr)prints a code.Arrays.sortsorts in place and returns nothing; sort a copy when you must keep the original order.Arrays.copyOfandcopyOfRangecreate real copies and can grow (zero-padded) or shrink;b = acopies only the pointer.- Compare contents with
Arrays.equals;==and.equalson arrays compare identity. - A copy of a 2D array shares its rows unless you copy each row.
Next lesson
The next lesson, "Demo: student-grade manager with arrays", puts arrays, loops, methods, and Strings together to build the core of the module lab.
Self-check
- How do you print an array readably?
- Does
Arrays.sort(a)return a new array? - How do you make a real copy of
a? - How do you compare two arrays by content?
- Why is
Arrays.copyOf(grid, grid.length)not an independent copy of a 2D array?
أظهر الإجابات
Arrays.toString(a).- No. It sorts
ain place and returns nothing. int[] c = Arrays.copyOf(a, a.length);Arrays.equals(a, b).- It copies the outer array of row pointers only, so the original and the copy still share the same inner rows.
References
- Oracle,
Arraysclass, Java SE 21 API. It supports:toString,deepToString, in-place ascendingsort(with a range form that throwsArrayIndexOutOfBoundsExceptionfor an invalid range),copyOf(truncates or pads with default values),copyOfRange(end excluded),fill,equals, anddeepEquals. - Oracle, Java Language Specification SE 21, chapter 10: Arrays. It supports: a multi-dimensional array is an array of references to sub-arrays, and cloning is shallow with respect to them.
- Not verified from a primary page: that
String[]sorts upper-case before lower-case (a run with JDK 21 gave[Zebra, apple, banana], consistent with character-code order), and the exact text of the[I@...form (the examples confirm its start by running JDK 21). All outputs were produced by running the code with JDK 21.
التطبيق
طبّق هذا الدرس بمختبر الوحدة وتمارينها واختبارها.
تعليم الدرس كمكتمل اختياري ويمكنك التراجع عنه في أي وقت. يبقى تقدمك محفوظًا في هذا المتصفح.