[英]Removing Duplicates from Array of Int[]
I have really been struggling with this for an hour or so now. 我真的已经为此挣扎了一个小时左右。 I am trying to remove all the duplicates from an array of int[].
我正在尝试从int []数组中删除所有重复项。 Every element of the array is a int[] containing the x & y positions of a tile.
数组的每个元素都是一个int [],其中包含图块的x和y位置。 So, the it is [[3, 1], [3, 12], ...].
因此,它是[[3,1],[3,12],...]。 When generating my world, I add already seen tiles, so I am writing a function to "condense" the tile array.
生成世界时,我添加了已经看到的图块,因此我正在编写一个“压缩”图块数组的函数。
I have tried using a hashSet & set, but for some reason, both DS do not remove the duplicates. 我尝试使用hashSet&set,但是由于某些原因,两个DS都不会删除重复项。 Is there possibly an issue with overriding compare(object1, object2) for int[]'s?
覆盖int []的compare(object1,object2)可能有问题吗?
// Takes array of x,y coordinates (form: int[]{x, y}) and condense it by removing the duplicates //获取x,y坐标数组(形式:int [] {x,y}),并通过删除重复项进行压缩
private int[][] condenseTiles(int[][] tiles) {
Set<int[]> setOfTiles = new LinkedHashSet<int[]>();
for(int i = 0; i < tiles.length; i++){
setOfTiles.add(tiles[i]);
}
System.out.println(setOfTiles.size());
return tiles;
}
I know there are shortcut ways to add every element to a HashSet, but currently nothing is working and I am still seeing duplicates, so I'm just doing it the slow and expanded way. 我知道可以将每个元素添加到HashSet的捷径方法,但是目前没有任何效果,而且仍然看到重复项,因此我只是在缓慢而扩展地进行操作。 For reference, right now, setOfTiles and tiles have the same size no matter what I do.
作为参考,无论我做什么,setOfTiles和tile的大小都相同。 Please let me know if you have any suggestions.
如果您有任何建议,请告诉我。
One possible solution: 一种可能的解决方案:
public boolean equals(Object o)
and public int hashCode()
methods, one that regards two Tiles with the same x and y values as being equal and as returning the same hashCode public boolean equals(Object o)
和public int hashCode()
方法,该方法将两个具有相同x和y值的Tile视为相等并返回相同的hashCode Set<Tile>
from the start -- this prevents duplicate entry. Set<Tile>
放置在Set<Tile>
-这样可以防止重复输入。 eg, 例如,
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 + "]";
}
}
And tested with: 并测试了:
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();
}
}
}
Which returns: 哪个返回:
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]
Another possible solution, if you want to use Java 8 streams, note that it has a .filter()
method, but this only works with the hashCode and the equals of the objects being streamed, and if you're streaming int arrays by themselves, this simply won't work. 另一个可能的解决方案,如果要使用Java 8流,请注意,它具有
.filter()
方法,但这仅适用于hashCode和要被流传输的对象的.filter()
,并且如果您自己是通过流传输int数组,这根本行不通。 A work around is to use a wrapper class, similar to this Stack Overflow answer on "Remove duplicates from a list of objects based on property in Java 8" . 一种解决方法是使用包装器类,类似于关于“根据Java 8中的属性从对象列表中删除重复项”的Stack Overflow答案 。
A wrapper class that might work: 一个可能起作用的包装器类:
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;
}
}
And this can be tested like so: 可以这样测试:
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));
}
}
}
Which returns: 哪个返回:
before filtering:
[1, 2]
[3, 4]
[5, 6]
[1, 2]
[5, 6]
after filtering:
[1, 2]
[3, 4]
[5, 6]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.