集合的特点
不存放重复的元素
常用于去重
- 存放新增 IP,统计新增 IP 量
- 存放词汇,统计词汇量
...
接口设计
package com.njf;
public interface Set<E> {
int size();
boolean isEmpty();
void clear();
boolean contains(E element);
void add(E element);
void remove(E element);
/*
* 遍历
*/
void traversal(Visitor<E> visitor);
/*
* 抽象类
*/
public static abstract class Visitor<E> {
boolean stop;
public abstract boolean visit(E element);
}
}
集合的内部实现可以直接利用前面章节提到的数据结构
动态数组,链表,二叉搜索树(AVL树、红黑树)
也可以用下一章节的Map实现
Map中的key是唯一的,符合集合的特点
用双向链表实现
package com.njf;
public class ListSet<E> implements Set<E>{
private DoublyLinkedList<E> list = new DoublyLinkedList<>();
@Override
public int size() {
return list.size();
}
@Override
public boolean isEmpty() {
return list.isEmpty();
}
@Override
public void clear() {
list.clear();
}
@Override
public boolean contains(E element) {
return list.contains(element);
}
@Override
public void add(E element) {
int index = list.indexOf(element);
if (index != list.ELEMENT_NOT_FOUND) {
list.set(index, element);
}else {
list.add(element);
}
}
@Override
public void remove(E element) {
int index = list.indexOf(element);
if (index != list.ELEMENT_NOT_FOUND) {
list.remove(index);
}
}
@Override
public void traversal(Visitor<E> visitor) {
if (visitor == null) return;
int size = list.size();
for (int i = 0; i < size; i++) {
if(visitor.visit(list.get(i))) return;
}
}
}
代码调用
package com.njf;
import com.njf.Set.Visitor;
public class Main {
static void test1() {
Set<Integer> listSet = new ListSet<>();
listSet.add(10);
listSet.add(11);
listSet.add(11);
listSet.add(12);
listSet.add(10);
listSet.traversal(new Visitor<Integer>() {
@Override
public boolean visit(Integer element) {
System.out.println(element);
return false;
}
});
}
public static void main(String[] args) {
test1();
}
}
打印结果:
10
11
12
用红黑树实现
package com.njf;
import java.util.Comparator;
public class TreeSet<E> implements Set<E> {
private RBTree<E> rb;
public TreeSet() {
this(null);
}
public TreeSet(Comparator<E> comparator) {
rb = new RBTree<>(comparator);
}
@Override
public int size() {
return rb.size;
}
@Override
public boolean isEmpty() {
return rb.isEmpty();
}
@Override
public void clear() {
rb.clear();
}
@Override
public boolean contains(E element) {
return rb.contains(element);
}
@Override
public void add(E element) {
rb.add(element);
}
@Override
public void remove(E element) {
rb.remove(element);
}
@Override
public void traversal(Visitor<E> visitor) {
rb.inorder(new BinaryTree.Visitor<E>() {
@Override
public boolean visit(E element) {
return visitor.visit(element);
}
});
}
}
代码调用:
package com.njf;
import com.njf.Set.Visitor;
public class Main {
static void test2() {
Set<Integer> treeSet = new TreeSet<>();
treeSet.add(12);
treeSet.add(10);
treeSet.add(7);
treeSet.add(11);
treeSet.add(10);
treeSet.add(11);
treeSet.add(9);
treeSet.traversal(new Visitor<Integer>() {
@Override
public boolean visit(Integer element) {
System.out.println(element);
return false;
}
});
}
public static void main(String[] args) {
test1();
}
}
打印结果:
7
9
10
11
12
红黑树的实现,元素必须具备可比较性
Map实现
package com.njf;
public class MapSet<E> implements Set<E> {
private Map<E, Object> map = new TreeMap<>();
@Override
public int size() {
return map.size();
}
@Override
public boolean isEmpty() {
return map.isEmpty();
}
@Override
public void clear() {
map.clear();
}
@Override
public boolean contains(E element) {
return map.containsKey(element);
}
@Override
public void add(E element) {
map.put(element, null);
}
@Override
public void remove(E element) {
map.remove(element);
}
@Override
public void traversal(Visitor<E> visitor) {
map.traversal(new Map.Visitor<E, Object>() {
@Override
public boolean visit(E key, Object value) {
return visitor.visit(key);
}
});
}
}