Проверка, равны ли два массива
Проверить, равны ли два массива, можно легко с помощью Arrays.equals()
метода. Этот метод флага доступен во многих вариантах для примитивных типов Object
и обобщений. Он также поддерживает компараторы . Давайте рассмотрим следующие три массива целых чисел:
Джава
1
int[] integers1 = {3, 4, 5, 6, 1, 5};
2
int[] integers2 = {3, 4, 5, 6, 1, 5};
3
int[] integers3 = {3, 4, 5, 6, 1, 3};
Вам также может понравиться метод JDK 12 Files.mismatch
Теперь давайте проверим, integers1
равно integers2
ли integers1
и равно ли integers3
. Это очень просто:
Джава
xxxxxxxxxx
1
boolean i12 = Arrays.equals(integers1, integers2); // true
2
boolean i13 = Arrays.equals(integers1, integers3); // false
Предыдущие примеры проверяют, равны ли два массива, но мы можем проверить, равны ли два сегмента (или диапазона) массивов, с помощью следующего метода:
Джава
xxxxxxxxxx
1
boolean equals(int[] a, int aFromIndex,
2
int aToIndex, int[] b, int bFromIndex, int bToIndex)
Итак, мы разграничиваем сегмент первого массива с помощью range [ aFromIndex
, aToIndex
) и сегмент второго массива с помощью range [ bFromIndex
, bToIndex
):
Джава
1
// true
2
boolean is13 = Arrays.equals(integers1, 1, 4, integers3, 1, 4);
Теперь давайте предположим три массива Melon
:
Джава
xxxxxxxxxx
1
public class Melon {
2
3
private final String type;
4
private final int weight;
5
6
public Melon(String type, int weight) {
7
this.type = type;
8
this.weight = weight;
9
}
10
11
12
public int hashCode() {
13
int hash = 7;
14
hash = 83 * hash + Objects.hashCode(this.type);
15
hash = 83 * hash + this.weight;
16
return hash;
17
}
18
19
20
public boolean equals(Object obj) {
21
22
if (this == obj) {
23
return true;
24
}
25
26
if (obj == null) {
27
return false;
28
}
29
30
if (getClass() != obj.getClass()) {
31
return false;
32
}
33
34
final Melon other = (Melon) obj;
35
if (this.weight != other.weight) {
36
return false;
37
}
38
39
if (!Objects.equals(this.type, other.type)) {
40
return false;
41
}
42
43
return true;
44
}
45
}
46
47
Melon[] melons1 = {
48
new Melon("Horned", 1500), new Melon("Gac", 1000)
49
};
50
51
Melon[] melons2 = {
52
new Melon("Horned", 1500), new Melon("Gac", 1000)
53
};
54
55
Melon[] melons3 = {
56
new Melon("Hami", 1500), new Melon("Gac", 1000)
57
};
Два массива Object
считаются равными на основании equals()
договора или на основании указанного Comparator
. Мы можем легко проверить, melons1
равно melons2
ли melons1
оно и равно ли melons3
:
Джава
xxxxxxxxxx
1
boolean m12 = Arrays.equals(melons1, melons2); // true
2
boolean m13 = Arrays.equals(melons1, melons3); // false
И в явном диапазоне мы можем использовать следующий метод:
Джава
xxxxxxxxxx
1
boolean equals(Object[] a, int aFromIndex,
2
int aToIndex, Object[] b, int bFromIndex, int bToIndex)
Например:
Джава
xxxxxxxxxx
1
boolean ms13 = Arrays.equals(melons1, 1, 2, melons3, 1, 2); // false
Хотя эти примеры опираются на Melon.equals()
реализацию, следующие два примера опираются на следующие два Comparator
:
Джава
xxxxxxxxxx
1
Comparator<Melon> byType = Comparator.comparing(Melon::getType);
2
Comparator<Melon> byWeight = Comparator.comparing(Melon::getWeight);
Используя boolean equals(T[] a, T[] a2, Comparator<? super T> cmp)
, мы имеем следующее:
Джава
xxxxxxxxxx
1
boolean mw13 = Arrays.equals(melons1, melons3, byWeight); // true
2
boolean mt13 = Arrays.equals(melons1, melons3, byType); // false
И, в явном диапазоне, используя:
Джава
xxxxxxxxxx
1
Comparator, <T> boolean equals(T[] a, int aFromIndex, int aToIndex, T[] b,
2
int bFromIndex, int bToIndex, Comparator<? super T> cmp)
У нас есть следующее:
Джава
xxxxxxxxxx
1
// true
2
boolean mrt13 = Arrays.equals(melons1, 1, 2, melons3, 1, 2, byType);
Проверка того, что два массива содержат несоответствия
Если два массива равны, несоответствие должно возвращать -1. Но если два массива не равны, тогда несоответствие должно возвращать индекс первого несоответствия между двумя данными массивами. Чтобы решить эту проблему, мы можем положиться на Arrays.mismatch()
методы JDK 9 .
Например, мы можем проверить несоответствия между integers1
и integers2
следующим образом:
Джава
xxxxxxxxxx
1
int mi12 = Arrays.mismatch(integers1, integers2); // -1
Результат -1, так как integers1
и integers2
равен. Но если мы проверим integers1
и integers3
, мы получим значение 5, которое является индексом первого несоответствия между этими двумя:
Джава
xxxxxxxxxx
1
int mi13 = Arrays.mismatch(integers1, integers3); // 5
Если данные массивы имеют разную длину и меньший является префиксом для большего, то возвращаемое несоответствие является длиной меньшего массива.
Для массивов Object
есть специальные mismatch()
методы. Эти методы рассчитывают на equals()
контракт или на данный Comparator
. Мы можем проверить, есть ли несоответствие между melons1
и melons2
следующим образом:
Джава
xxxxxxxxxx
1
int mm12 = Arrays.mismatch(melons1, melons2); // -1
Если в первом индексе происходит несовпадение, возвращаемое значение равно 0. Это происходит в случае melons1
и melons3
:
Джава
xxxxxxxxxx
1
int mm13 = Arrays.mismatch(melons1, melons3); // 0
Как и в случае с Arrays.equals()
, мы можем проверить несоответствия в явном диапазоне, используя Comparator
:
Джава
xxxxxxxxxx
1
// range [1, 2), return -1
2
int mms13 = Arrays.mismatch(melons1, 1, 2, melons3, 1, 2);
3
4
// Comparator by melon's weights, return -1
5
int mmw13 = Arrays.mismatch(melons1, melons3, byWeight);
6
7
// Comparator by melon's types, return 0
8
int mmt13 = Arrays.mismatch(melons1, melons3, byType);
9
10
// range [1,2) and Comparator by melon's types, return -1
11
int mmrt13 = Arrays.mismatch(melons1, 1, 2, melons3, 1, 2, byType);
Готово!
Полный исходный код доступен на GitHub .
Если вам понравилась эта статья, то я уверен, что вам понравится моя книга « Проблемы кодирования Java» , в которой есть целая глава, посвященная массивам, коллекциям и структурам данных.