/*
* Copyright (c) 2002-2012 Alibaba Group Holding Limited.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.toolkit.util.collection;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
/**
* <p>
* 一个集合的实现, 实现了<code>Set</code>接口.
* </p>
* <p>
* 这个集合在内部使用<code>ArrayHashMap</code>保存集合中的元素, 因而具有以下特性:
* </p>
* <ul>
* <li>不同于<code>HashMap</code>, 集合中元素的顺序是确定的</li>
* <li>和<code>ArrayHashMap</code>一样, 没有进行任何<code>synchronized</code>操作</li>
* </ul>
*
* @author Michael Zhou
* @version $Id: ArrayHashSet.java,v 1.1 2003/07/03 07:26:15 baobao Exp $
* @see ArrayHashMap
*/
public class ArrayHashSet extends AbstractSet implements Set, Cloneable, Serializable {
/*
* ==========================================================================
* ==
*/
/* 常量 */
/*
* ==========================================================================
* ==
*/
/** 表示内部hash表的值. */
private static final Object PRESENT = new Object();
/*
* ==========================================================================
* ==
*/
/* 成员变量 */
/*
* ==========================================================================
* ==
*/
/** 内部的hash表. */
protected transient ArrayHashMap map;
/*
* ==========================================================================
* ==
*/
/* 构造函数 */
/*
* ==========================================================================
* ==
*/
/** 创建一个空的集合. 使用指定的默认的初始容量(16)和默认的负载系数(0.75). */
public ArrayHashSet() {
map = new ArrayHashMap();
}
/**
* 创建一个空的集合. 使用指定的初始阈值和默认的负载系数(0.75).
*
* @param initialCapacity 初始容量.
*/
public ArrayHashSet(int initialCapacity) {
map = new ArrayHashMap(initialCapacity);
}
/**
* 创建一个空的集合. 使用指定的初始容量和负载系数.
*
* @param initialCapacity 初始容量
* @param loadFactor 负载系数.
*/
public ArrayHashSet(int initialCapacity, float loadFactor) {
map = new ArrayHashMap(initialCapacity, loadFactor);
}
/**
* 创建一个空的集合, 并复制指定的<code>Collection</code>的所有项到这个集合中. 使用默认的负载系数(0.75).
*
* @param collection 要复制的<code>Collection</code>
*/
public ArrayHashSet(Collection collection) {
map = new ArrayHashMap(Math.max((int) (collection.size() / .75f) + 1, 16));
addAll(collection);
}
/*
* ==========================================================================
* ==
*/
/* 实现Set接口的方法 */
/*
* ==========================================================================
* ==
*/
/**
* 返回集合中entry的个数.
*
* @return 集合中的entry数.
*/
@Override
public int size() {
return map.size();
}
/**
* 判断是否为空的集合.
*
* @return 如果为空(<code>size() == 0</code>), 则返回<code>true</code>.
*/
@Override
public boolean isEmpty() {
return map.isEmpty();
}
/**
* 如果集合中包含指定值, 则返回<code>true</code>.
*
* @param object 测试指定值是否存在.
* @return 如果指定值存在, 则返回<code>true</code>.
*/
@Override
public boolean contains(Object object) {
return map.containsKey(object);
}
/**
* 将指定的值加入到集合中.
*
* @param object 要加入的值
* @return 如果集合中已经存在此值, 则返回<code>false</code>. 否则返回<code>true</code>.
*/
@Override
public boolean add(Object object) {
return map.put(object, PRESENT) == null;
}
/**
* 将指定值从集合中删除(如果该值存在的话).
*
* @param object 要被删除的值
* @return 如果被删除的值原来不存在, 则返回<code>false</code>, 否则返回<code>true</code>
*/
@Override
public boolean remove(Object o) {
return map.remove(o) == PRESENT;
}
/** 清除集合中的所有对象. */
@Override
public void clear() {
map.clear();
}
/**
* 取得集合中所有项的遍历器.
*
* @return 集合中所有项的遍历器
*/
@Override
public Iterator iterator() {
return map.keySet().iterator();
}
/*
* ==========================================================================
* ==
*/
/* 复制方法(Clonable接口) */
/*
* ==========================================================================
* ==
*/
/**
* "浅"拷贝集合, 集合中的对象本身并不被复制.
*
* @return 被复制的集合.
*/
@Override
public Object clone() {
try {
ArrayHashSet newSet = (ArrayHashSet) super.clone();
newSet.map = (ArrayHashMap) map.clone();
return newSet;
} catch (CloneNotSupportedException e) {
throw new InternalError(); // 不支持clone(不可能).
}
}
/*
* ==========================================================================
* ==
*/
/* 序列化 */
/*
* ==========================================================================
* ==
*/
/** 序列化版本号. */
private static final long serialVersionUID = -5024744406713321676L;
/**
* 从输入流中重建集合(也就是反序列化).
*
* @param is 输入流
* @throws IOException 输入流异常
* @throws ClassNotFoundException 类未找到
*/
private synchronized void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException {
is.defaultReadObject();
int capacity = is.readInt();
float loadFactor = is.readFloat();
map = new ArrayHashMap(capacity, loadFactor);
int size = is.readInt();
for (int i = 0; i < size; i++) {
Object e = is.readObject();
map.put(e, PRESENT);
}
}
/**
* 将集合的状态保存到输出流中(也就是序列化).
*
* @param os 输出流
* @throws IOException 输出流异常
*/
private synchronized void writeObject(ObjectOutputStream os) throws IOException {
os.defaultWriteObject();
os.writeInt(map.getCapacity());
os.writeFloat(map.getLoadFactor());
os.writeInt(map.size());
for (Iterator i = map.keySet().iterator(); i.hasNext(); ) {
os.writeObject(i.next());
}
}
}