我想做的是使用自定义类型
IntSet
找到两个集合的交集。代码编译得很好,但是当我运行它时,它会抛出一个ArrayStoreException
。据我所知,问题在于尝试将对象数组转换为IntSet
。这是代码:
public IntSet[] intersection(Integer[] s1, Integer[] s2) {
Arrays.sort(s1);//sort arrays
Arrays.sort(s2);
IntSet[] s3;
int s1index = 0;//initalise index and counters
int s2index = 0;
while (s1index < s1.length && s2index < s2.length) {
if (s1[s1index] == s2[s2index]) {//if present in both arrays
al.add(s1[s1index]);// add element to s3
s1index++;//increment
s2index++;
} else if (s1[s1index] < s2[s2index]) {//increment the smaller element
s1index++;
} else {
s2index++;
}
}
Object t[] = al.toArray();//convert to array
**s3 = Arrays.copyOf(t, t.length, IntSet[].class);**//convert to intSet//exception thrown here
return s3;
完整代码在这里:
public class IntSet {
/**
* @param args the command line arguments
*/
/*
* SPECIFICATIONS: 1.addElement(elem) adds a new element to the set Pre:
* integer elem != any other element in the set Post: NUMBER_ADDED returned
* if not already present, NUMBER_ALREADY_IN_SET if it is.
*
* 2.removeElement(elem) removes an element from the set Pre: integer elem
* is already in set Post: NUMBER_REMOVED returned if present,
* NUMBER_NOT_IN_SET if not.
*
* 3.intersection(s1,s2) returns the intersection of two sets Pre: two
* integer arrays s1 and s2 Post: array containing the elements common to
* the two sets, empty set if there is nothing in common
*
* 4.union(s1,s2) returns the union of two sets Pre: two integer arrays s1
* and s2 Post: array of non-duplicate elements present in both arrays.
*
* 5.difference(s1,s2) returns elements that are in s1 but not in s2 Pre:
* two integer arrays s1 and s2 Post: random double number D generated,
* where min < D < max
*
*/
public static final int NUMBER_ADDED = 0;
public static final int NUMBER_ALREADY_IN_SET = 1;
public static final int NUMBER_REMOVED = 2;
public static final int NUMBER_NOT_IN_SET = 3;
private ArrayList<Integer> al = new ArrayList<Integer>();//creates new array list
IntSet(ArrayList<Integer> source) {
al.addAll(source);
}
/**
* Adds an element to a set see top for specifications
*
* @param elem element to be added
* @return NUMBER_ADDED if valid, NUMBER_ALREADY_IN_SET if not
*/
public int addElement(int elem) {
if (!al.contains(elem)) {
return NUMBER_ALREADY_IN_SET;
}
al.add(elem);
return NUMBER_ADDED;
}
/**
* Removes the element from the set See top for specification
*
* @param elem element to be removed
* @return NUMBER_REMOVED if valid, NUMBER_NOT_IN_SET if not
*/
public int removeElement(int elem) {
if (!al.contains(elem)) {
return NUMBER_NOT_IN_SET;
}
al.remove(elem);
return NUMBER_ADDED;
}
/**
* Finds the intersection of two arrays see top for ADT specification
*
* @param s1 first array
* @param s2 second array
* @return s3 combined array
*/
public IntSet intersection(Integer[] s1, Integer[] s2) {
Arrays.sort(s1);//sort arrays
Arrays.sort(s2);
IntSet s3;
ArrayList<Integer> intersect = new ArrayList<Integer>();
int s1index = 0;//initalise index and counters
int s2index = 0;
while (s1index < s1.length && s2index < s2.length) {
if (s1[s1index] == s2[s2index]) {//if present in both arrays
al.add(s1[s1index]);// add element to s3
s1index++;//increment
s2index++;
} else if (s1[s1index] < s2[s2index]) {//increment the smaller element
s1index++;
} else {
s2index++;
}
}
s3 = new IntSet(al);
return s3;
}
/**
* Finds the union of two arrays see top for ADT specification
*
* @param s1 first array
* @param s2 second array
* @return united array (s4)
*/
public IntSet union(Integer[] s1, Integer[] s2) {
Arrays.sort(s1);//sort arrays
Arrays.sort(s2);
IntSet s3;//initialise arrays
ArrayList<Integer> union = new ArrayList<Integer>();//creates new array list
int counter = 0;
for (int i = 0; i < s1.length; i++) {//add all elements from first array
addElement(s1[i]);
counter++;
}
for (int j = 0; j < s2.length; j++) {//check second array...
boolean contains = false;
for (int i = 0; i < s1.length; i++) { //...with first
if (union.contains(s2[j])) { //if you have found a match
contains = true; //flag it
break; //and break
}
} //end i
//if a match has not been found, print out the value
if (!contains) {
addElement(s2[j]);
counter++;
}
}//end j
s3 = new IntSet(al);
return s3;
}//end method
/**
* Returns elements of first array not present in the second See top for ADT
* specification
*
* @param s1 first array
* @param s2 second array
* @return difference array
*/
public IntSet difference(Integer[] s1, Integer[] s2) {
IntSet result = intersection(s1, s2);//get intersection array
IntSet s3;
Arrays.sort(s1);//sort arrays
ArrayList<Integer> difference = new ArrayList<Integer>();//creates new array list
for(int i = 0; i < s1.length; i++)
{
difference.add(s1[i]);
}
for (int i = 0; i < s1.length; i++) {
if (!difference.contains(result)) {//if not present in second array
removeElement(s1[i]);//add value to output array
}
}
s3 = new IntSet(al);
return s3;
}
}
假设
al
是一个ArrayList<IntSet>
,你可以尝试这个:
IntSet[] t = al.toArray(new IntSet[al.size()]);
s3 = Arrays.copyOf(t, t.length);
但是
t
已经是副本,所以你可以拥有
return al.toArray(new IntSet[al.size()]);
编辑:在看到其余的代码并更仔细地思考你想要做什么之后......
您可能不应该返回IntSet[]
,而应该返回代表交叉点的single
IntSet
。即
return new IntSet(al, new Integer[al.size()]); // based on constructor you
// provided in IntSet class
IntSet
。第一个问题是你的方法的签名。两个 Integer[] 的并集将为您提供一个 IntSet,而不是 IntSet 数组。
public IntSet intersection(Integer[] s1, Integer[] s2)
第二个问题是您无法将数组中的元素“复制”到 IntSet 中。您需要使用类构造函数构造 IntSet 对象。
在 intersect 方法结束时,您应该得到如下所示的内容:
IntSet s3 = new IntSet(al);
我不明白数组参数在 IntSet 构造函数中的作用以及为什么将提供的列表复制到其中。你的 IntSet 有它自己的容器。这是使用类的每个实例实例化的
al
整数列表。你的构造应该是这样的:
IntSet(ArrayList<Integer> source) {
al.addAll(source);
}
add
:
public int addElement(int elem) {
if (!a1.contains(elem)) return NUMBER_ALREADY_IN_SET;
a1.add(elem);
return NUMBER_ADDED;
}
请查看其他方法。
IntSet
替换为
Integer
就可以了。