Set是java中的一种数据结构,或者说一种集合,它其实是一个接口,通过帮助文档我们可以看到有哪些类实现了它
但是有很多方法不常用到,今天我们自定义一个高仿set的数据结构,需要实现的方法如下图
底层接口setADT
public void add(T element); 添加一个元素
public T removeRandom(); 随机移除一个元素
public T remove(T element); 移除指定的元素
public String toSting(); 转换为字符串
public SetADT<T> union(SetADT<T> set); 求两个set的交集
public boolean contains(T element); 是否包含某元素
public boolean equals(SetADT<T> set); 是否和另一个set相等
public void addAll(SetADT<T> set); 将另一个set的元素添加过来
public boolean isEmpty(); 判定该set是否为空
public int size(); 返回set的长度
public Iterator<T> iterator(); 返回set的迭代器
接下来用一个类来实现这个接口,我们先实现 它的顺序存储形式,还有另外一种为链式存储(linkset),顺序存储,用array来实现
package packageSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Random;
import java.util.Set;
public class ArraySet<T> implements SetADT<T>{
//指定数组容量
private final int DEFAULT_CAPACITY = 100;
private final int NOT_FOUND = -1;
private Random random;
//count表示存在数组中的元素个数
private int count;
//contents表示数组
private T[] contents;
//构造函数
public ArraySet() {
// TODO 自动生成的构造函数存根
count = 0;
contents = (T[])(new Object[DEFAULT_CAPACITY]);
}
//含参数的构造函数
public ArraySet(int initialCapacity){
count = 0;
contents = (T[])(new Object[initialCapacity]);
}
//
@Override
public void add(T element) {
// TODO 自动生成的方法存根
//由于set中不存在重复的元素,因此每次添加元素的时候,都需要
//检查set中是否已经存在该元素
if(!(contains(element)))
{
//当长度与数组最大容量相等时,扩充数组
if(size() == contents.length){
expandCapacity();
}
contents[count] = element;
count++;
}
}
//随机从set中移除一个元素
@Override
public T removeRandom(){
// TODO 自动生成的方法存根
if(isEmpty()){
try {
throw new Exception();
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
//产生0-(count-1)的随机数
random = new Random();
int choice = random.nextInt(count);
//将要移除的数result
T result = contents[choice];
//set不要求次序,则可以将最后一个元素放到移除的位置即可
contents[choice] = contents[count-1];
contents[count-1] = null;
return result;
}
@Override
public T remove(T integer) throws NoSuchElementException{
// TODO 自动生成的方法存根
int search = NOT_FOUND;
if (isEmpty()) {
try {
throw new Exception();
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
//遍历数组
for(int i = 0;i<count && search == NOT_FOUND;i++)
{
//将i的值赋给search
if (contents[i].equals(integer)) {
search = i;
}
if(search == NOT_FOUND)
{
throw new NoSuchElementException();
}
}
T result = contents[search];
contents[search] = contents[count-1];
contents[count-1] = null;
count--;
return result;
}
@Override
public String toSting() {
// TODO 自动生成的方法存根
String result = "";
for (int i = 0; i < count; i++) {
result = result +contents[i].toString()+"\n";
}
return result;
}
@Override
public SetADT<T> union(SetADT<T> set) {
// TODO 自动生成的方法存根
return null;
}
@Override
public boolean contains(T integer) {
// TODO 自动生成的方法存根
int search = NOT_FOUND;
//遍历数组,寻找是否有和o相等的元素
for(int i = 0;i<count && search == NOT_FOUND;i++)
{
if (contents[i] == integer) {
search = i;
}
}
return (search!= NOT_FOUND);
}
@Override
public boolean equals(SetADT<T> set) {
// TODO 自动生成的方法存根
boolean result =false;
ArraySet<T> temp1 = new ArraySet<T>();
ArraySet<T> temp2 = new ArraySet<T>();
T integer;
if(size() == set.size()){
temp1.addAll(this);
temp2.addAll(set);
Iterator<T> iterator = set.iterator();
while(iterator.hasNext())
{
integer = iterator.next();
if(temp1.contains(integer))
{
temp1.remove(integer);
temp2.remove(integer);
}
}
result = (temp1.isEmpty()) && temp2.isEmpty();
}
return result;
}
//添加一个set中的元素,用迭代器方法
@Override
public void addAll(SetADT<T> set) {
// TODO 自动生成的方法存根
Iterator<T> it = set.iterator();
while(it.hasNext()){
add(it.next());
}
}
@Override
public boolean isEmpty() {
// TODO 自动生成的方法存根
return (count == 0);
}
@Override
public int size() {
// TODO 自动生成的方法存根
return count;
}
@Override
public Iterator<T> iterator() {
// TODO 自动生成的方法存根
return new ArrayIterator<T>(contents, count);
}
public void expandCapacity()
{
T[] larger = (T[]) new Object[contents.length*2];
for (int i = 0; i < contents.length; i++) {
larger[i] = contents[i];
}
contents = larger;
}
}
接下来测试各个方法是否可用
创建一个test类
package packageSet;
import java.util.Iterator;
public class ArraySetTest {
public static void main(String[] args) {
// TODO 自动生成的方法存根
ArraySet<Integer> set1 = new ArraySet<Integer>();
set1.add(20);
set1.add(23);
set1.add(34);
set1.add(55);
set1.add(21);
set1.add(21);
set1.add(32);
set1.add(32);
set1.add(90);
set1.add(22);
set1.add(27);
set1.add(28);
set1.add(24);
set1.add(72);
set1.add(26);
Iterator<Integer> iterator1 = set1.iterator();
while(iterator1.hasNext())
{
System.out.print(iterator1.next()+" ");
}
System.out.println("\n====================================");
System.out.println(set1.removeRandom());
Iterator<Integer> iterator2 = set1.iterator();
while(iterator2.hasNext())
{
System.out.print(iterator2.next()+" ");
}
System.out.println("\n----------------------------------------");
System.out.println(set1.contains(34));
ArraySet<Integer> set2 = new ArraySet<Integer>();
set2.add(24);
set2.add(45);
set2.add(78);
set2.add(45);
set2.add(88);
set2.add(32);
set2.add(90);
set2.add(82);
set2.add(21);
set2.add(23);
set2.add(89);
set2.add(32);
set2.add(77);
set2.add(89);
Iterator<Integer> it = set2.iterator();
while(it.hasNext())
{
System.out.print(it.next()+" ");
}
System.out.println(set1.equals(set2));
System.out.println("\n+++++++++++++++++++++++++++++++++++++++++");
set1.addAll(set2);
Iterator<Integer> iterator3 = set1.iterator();
while(iterator3.hasNext())
{
System.out.print(iterator3.next()+" ");
}
System.out.println("\n****************************************");
ArraySet<String> setString = new ArraySet<String>();
setString.add("hello");
setString.add("i'm");
setString.add("a");
setString.add("string");
Iterator<String> it2 = setString.iterator();
while(it2.hasNext())
{
System.out.print(it2.next()+" ");
}
}
}
输出结果如下:
ok,方法可用,这样就实现了set的顺序存储结构