一种可能的解决方案:
- 创建一个 Tile 类,其中包含 x 和 y int 字段
- 为类提供像样的
public boolean equals(Object o) 和public int hashCode() 方法,一种将具有相同x 和y 值的两个Tiles 视为相等并返回相同hashCode 的方法
- 从一开始就将磁贴放在
Set<Tile> 中——这样可以防止重复输入。
例如,
public class Tile {
private int x;
private int y;
public Tile(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Tile other = (Tile) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
@Override
public String toString() {
return "Tile [" + x + ", " + y + "]";
}
}
并通过以下方式测试:
import java.util.LinkedHashSet;
import java.util.Set;
public class TestTile {
public static void main(String[] args) {
Set<Tile> tileSet = new LinkedHashSet<>();
int[][] testData = {{1, 2}, {3, 4}, {5, 6}, {1, 2}, {5, 6}};
for (int[] pair : testData) {
Tile tile = new Tile(pair[0], pair[1]);
tileSet.add(tile);
System.out.println("Tile added: " + tile);
System.out.println("All Tiles: ");
for (Tile t : tileSet) {
System.out.println(" " + t);
}
System.out.println();
}
}
}
返回:
Tile added: Tile [1, 2]
All Tiles:
Tile [1, 2]
Tile added: Tile [3, 4]
All Tiles:
Tile [1, 2]
Tile [3, 4]
Tile added: Tile [5, 6]
All Tiles:
Tile [1, 2]
Tile [3, 4]
Tile [5, 6]
Tile added: Tile [1, 2]
All Tiles:
Tile [1, 2]
Tile [3, 4]
Tile [5, 6]
Tile added: Tile [5, 6]
All Tiles:
Tile [1, 2]
Tile [3, 4]
Tile [5, 6]
另一种可能的解决方案,如果您想使用 Java 8 流,请注意它有一个 .filter() 方法,但这仅适用于正在流式传输的对象的 hashCode 和 equals,并且如果您正在流式传输 int 数组靠他们自己,这根本行不通。一种解决方法是使用包装类,类似于this Stack Overflow answer on "Remove duplicates from a list of objects based on property in Java 8"。
一个可能工作的包装类:
import java.util.Arrays;
public class WrapperArray {
int[] array;
public WrapperArray(int[] array) {
this.array = array;
}
@Override
public int hashCode() {
return Arrays.hashCode(array);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
WrapperArray other = (WrapperArray) obj;
if (!Arrays.equals(array, other.array))
return false;
return true;
}
public int[] unwrap() {
return array;
}
}
可以这样测试:
import java.util.Arrays;
public class TestTile {
public static void main(String[] args) {
int[][] testData = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 1, 2 }, { 5, 6 } };
System.out.println("before filtering:");
for (int[] is : testData) {
System.out.println(Arrays.toString(is));
}
int[][] filteredArray = Arrays.stream(testData) // stream int[][] array
.map(WrapperArray::new) // map to our wrapper objects
.distinct() // find distinct using wrapper equals/hashCode
.map(WrapperArray::unwrap) // convert back to int[]
.toArray(int[][]::new); // create new int[][] with results
System.out.println("after filtering:");
for (int[] is : filteredArray) {
System.out.println(Arrays.toString(is));
}
}
}
返回:
before filtering:
[1, 2]
[3, 4]
[5, 6]
[1, 2]
[5, 6]
after filtering:
[1, 2]
[3, 4]
[5, 6]