Java 如何使用HashSet在两个可比较的数组中查找公共元素?

Java 如何使用HashSet在两个可比较的数组中查找公共元素?,java,arrays,hashset,comparable,Java,Arrays,Hashset,Comparable,编辑:方法签名 public Comparable[][] findCommonElements(Comparable[][] collections) 这是错误的。应该是 public Comparable[] findCommonElements(Comparable[][] collections) 但在IDE中更改它会把一切都搞砸。我几乎觉得我已经超出了我的知识范围,因为我不完全理解集合,2D数组把我搞得一团糟 我需要编写一个算法,该算法采用两个可比较的数组,以线性时

编辑:方法签名

    public Comparable[][] findCommonElements(Comparable[][] collections)
这是错误的。应该是

    public Comparable[] findCommonElements(Comparable[][] collections)
但在IDE中更改它会把一切都搞砸。我几乎觉得我已经超出了我的知识范围,因为我不完全理解集合,2D数组把我搞得一团糟

我需要编写一个算法,该算法采用两个可比较的数组,以线性时间效率迭代,并显示公共元素。 我曾读到,使用哈希集可以让我获得最快的时间效率,但我已经陷入了僵局。原因如下:

我们得到了指令和一行代码,这就是方法签名

public Comparable[][] findCommonElements(Comparable[][] collections)
这意味着我必须返回2d数组“collections”。我给教授发了一封关于使用Hashset的电子邮件,得到了批准,但我遇到了以下问题:

您可以在findCommonElements方法中使用哈希集,但您需要能够计算执行的比较次数。虽然哈希通常非常有效,但在发生冲突时会进行一些比较。为此,您需要访问所使用哈希集的源代码。您还需要在CommonElements类中使用getComparations()“方法返回比较次数。”

在编程的两个学期中,我没有学习哈希集、映射、表等。我自己正在尝试学习这些,但我没有完全理解冲突

我的代码确实接受了这两个数组并返回了公共元素,但是我的返回语句很糟糕,因为我基本上是为了编译而编写的(2d Comparable数组就是参数)

我这样做对吗?代码如下:

public class CommonElements {

    static Comparable[] collection1 = {"A", "B", "C", "D", "E"}; //first array
    static Comparable[] collection2 = {"A", "B", "C", "D", "E", "F", "G"}; //second array
    static Comparable[][] collections = {collection1, collection2}; //array to store common elements. 
    static Set<Comparable> commonStuff = new HashSet<>(); //instance of Set containing common elements

    public static void main(String[] args) {

        CommonElements commonElements = new CommonElements(); //create instance of class CommonElements
        commonElements.findCommonElements(collections); //call the find method

    }
    public Comparable[][] findCommonElements(Comparable[][] collections) {

        Set<Comparable> addSet = new HashSet<>(); //instance of Set to add elements to

        for (Comparable x : collection1) { //adding elements from first array to my addSet
            addSet.add(x);
        }
        for (Comparable x : collection2) {
            if (addSet.contains(x)) {
            commonStuff.add(x); //checking for common elements, add to commonStuff Set
            }
        }
        System.out.println(toString(commonStuff)); //print the toString method

        return collections; //return statement, otherwise Java will whine at me
    }
    public String toString(Set<Comparable> commonStuff) { //this method gets rid of the brackets
        String elements = commonStuff.toString(); //make a String and assign it to the Set
        elements = elements.replaceAll("\\[", "").replaceAll("\\]", ""); //replace both brackets with empty space

        return "Common Elements: " + elements; //return the Set as a new String
    }
}
公共类公共元素{
静态可比[]集合1={“A”、“B”、“C”、“D”、“E”};//第一个数组
静态可比[]集合2={“A”、“B”、“C”、“D”、“E”、“F”、“G”};//第二个数组
静态可比较[]集合={collection1,collection2};//用于存储公共元素的数组。
静态集合commonStuff=newhashset();//包含公共元素的集合的实例
公共静态void main(字符串[]args){
CommonElements CommonElements=新建CommonElements();//创建CommonElements类的实例
commonElements.findCommonElements(集合);//调用find方法
}
公共可比[]findCommonElements(可比[]集合){
Set addSet=new HashSet();//要向其中添加元素的集合的实例
对于(可比较的x:collection1){//将元素从第一个数组添加到我的addSet
addSet.add(x);
}
用于(可比x:collection2){
if(addSet.contains(x)){
add(x);//检查公共元素,添加到CommonTuff集合
}
}
System.out.println(toString(commonStuff));//打印toString方法
return collections;//return语句,否则Java会对我发牢骚
}
公共字符串toString(Set commontuff){//此方法去掉括号
String elements=commonStuff.toString();//生成一个字符串并将其分配给集合
elements=elements.replaceAll(“\\[”,“”)。replaceAll(“\\]”,“”);//用空格替换两个括号
return“Common Elements:+Elements;//将集合作为新字符串返回
}
}
HashSet.add(E)
如果未能将
E
添加到
集,则返回false,因此我们可以说:

if (addSet.add(x)){
    //the collection did not contain x already
} else {
    //the collection contained x
}
所以你能做的就是这样:

public Comparable[] findCommonElements(){
    Set<Comparable> collectionSet1 = new HashSet<>(Arrays.asList(collection1));
    Set<Comparable> collectionSet2 = new HashSet<>(Arrays.asList(collection2));
    for (Comparable x : collectionSet1){
        if (!collectionSet2.add(x)){
            commonStuff.add(x);
        }
    }
    return commonStuff.toArray(); //convert HashSet to an array
}
public可比[]findCommonElements(){
Set collectionSet1=新的HashSet(Arrays.asList(collection1));
Set collectionSet2=新的HashSet(Arrays.asList(collection2));
用于(可比x:collectionSet1){
如果(!collectionSet2.add(x)){
添加(x);
}
}
返回commonStuff.toArray();//将哈希集转换为数组
}

注意,您需要
导入java.util.array

编辑我忘了提到我导入了apachecommons数组Utils。非常有用

我想出来了。谢谢你的帮助。我有一个main方法,它调用类的一个实例3次,还有3个测试方法,但这些都是无关的。这就是给我带来麻烦的原因,现在它起作用了。:-)

public int getcomparison(){
回报比较;
}//返回比较次数的方法
公共静态可比[]findCommonElements(可比[][]集合){
/*
我了解到我们必须使用两个以上的阵列,所以它又回来了
给我画板。不过我想出来了。
*/
Compariable[]arr1=collections[0];//将初始值设置为一维数组,以便测试方法可以读取各自的值
可比[]arr2=集合[1];
可比[]arr3=集合[2];
/*
以下代码块采用3个数组(即1,2,3;1,3,2;2,1,3等)的所有排列,
确定哪个数组最短,并将较长的两个数组添加到查询数组中。
*/

如果(arr1.lengthComparable
是通用的,因此您使用的是rawtype-don。其次,
HashSet
比较
等于
-
TreeSet
比较使用
Comparable
。请使用其中一个。不过,谢谢您的建议,阅读后告诉我,哈希集的时间复杂度更快。?是的,但它们只有在有哈希函数的情况下才起作用。事实上,您有
可比项
,这让我怀疑它不仅仅是
对象。hashCode()
实现。为什么要将参数定义为
可比[][]
如果您必须恰好收到两个
可比[]
,请定义两个
可比[]
参数。另外,获取
public int getComparisons() {
        return comparisons;
    } //method to return number of comparisons
    public static Comparable[] findCommonElements(Comparable[][] collections) {
        /*
        I LEARNED THAT WE HAD TO USE MORE THAN TWO ARRAYS, SO IT WAS BACK
        TO THE DRAWING BOARD FOR ME. I FIGURED IT OUT, THOUGH.
        */
        Comparable[] arr1 = collections[0]; //set initial values to 1 Dimensional arrays so the test methods can read their respective values
        Comparable[] arr2 = collections[1];
        Comparable[] arr3 = collections[2];

        /*
        THE FOLLOWING BLOCK OF CODE TAKES ALL THE PERMUTATIONS OF THE 3 ARRAYS (i.e. 1,2,3; 1,3,2; 2,1,3, etc),
        DETERMINES WHICH ARRAY IS THE SHORTEST, AND ADDS THE LONGER TWO ARRAYS TO A QUERY ARRAY.
         */
        if(arr1.length < arr2.length && arr1.length < arr3.length || arr2.length <= arr3.length) { //shortest array will become hash array. the other two will become a combined query array.
            hashArray = arr1;  //these will be utilized below to put into Sets
            queryArray = ArrayUtils.addAll(arr2, arr3);
        }
        else if(arr2.length < arr1.length && arr2.length < arr3.length || arr1.length <= arr3.length) {
            hashArray = arr2;
            queryArray = ArrayUtils.addAll(arr1, arr3);
        }
        else if(arr3.length < arr1.length && arr3.length < arr2.length || arr1.length <= arr2.length) {
            hashArray = arr3;
            queryArray = ArrayUtils.addAll(arr1, arr2);
        }
        HashSet<Comparable> intersectionSet = new HashSet<>(); //initialize Sets
        HashSet<Comparable> arrayToHash = new HashSet<>();
        for(Comparable element : hashArray) { //add shorter array to hashedArray Set
            arrayToHash.add(element);
        }
        //NOTE FROM THE JAVADOC ON THE IMPLEMENTATION OF .contains() USING HASHSET COMPARISONS
        /**
         * <p>This class offers constant time performance for the basic operations
         * (<tt>add</tt>, <tt>remove</tt>, <tt>contains</tt> and <tt>size</tt>),
         * assuming the hash function disperses the elements properly among the
         * buckets.
         */
        for(Comparable element : queryArray) {
            if(element != null) {
                comparisons++; // increment comparisons with each search
            }
            if(arrayToHash.contains(element)) { //search for matches and add to intersectionSet (.contains uses the equals method to determine if an object is within array)
                intersectionSet.add(element);
            }
        }
        return intersectionSet.toArray(new Comparable[0]); //return Set as Array defined in method signature
    }