`
i2534
  • 浏览: 182524 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java弱引用hashset和arraylist

    博客分类:
  • util
阅读更多

工作中需要用到弱引用的集合和列表.网上搜集了点资料,自己整理下发出来备份.

WeakHashSet是模仿HashSet的实现方式,使用WeakHashMap实现的.

WeakArrayList是修改自org.arakhne.util.ref下的WeakArrayList.

SpeedyKit.copyOf方法是1.6中Arrays下同名方法.我用的1.5,需要把此方法拷贝出来.

 

import java.util.AbstractSet;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.WeakHashMap;

/**
 * 参照{@link java.util.HashSet}实现的WeakHashSet.详细介绍参看{@link java.util.Set}和
 * {@link java.util.WeakHashMap}功能<br>
 * 
 */
public class WeakHashSet<E> extends AbstractSet<E> implements Set<E> {

	private transient WeakHashMap<E, Object>	map;

	private static final Object					PRESENT	= new Object();

	public WeakHashSet() {
		this.map = new WeakHashMap<E, Object>();
	}

	public WeakHashSet(Collection<? extends E> c) {
		this.map = new WeakHashMap<E, Object>(Math.max(
				(int) (c.size() / .75f) + 1, 16));
		this.addAll(c);
	}

	public WeakHashSet(int initialCapacity, float loadFactor) {
		this.map = new WeakHashMap<E, Object>(initialCapacity, loadFactor);
	}

	public WeakHashSet(int initialCapacity) {
		this.map = new WeakHashMap<E, Object>(initialCapacity);
	}

	public Iterator<E> iterator() {
		return this.map.keySet().iterator();
	}

	public int size() {
		return this.map.size();
	}

	@Override
	public boolean isEmpty() {
		return this.map.isEmpty();
	}

	@Override
	public boolean contains(Object o) {
		return this.map.containsKey(o);
	}

	@Override
	public boolean add(E o) {
		return this.map.put(o, WeakHashSet.PRESENT) == null;
	}

	@Override
	public boolean remove(Object o) {
		return this.map.remove(o) == WeakHashSet.PRESENT;
	}

	@Override
	public void clear() {
		this.map.clear();
	}
}

 

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.AbstractList;
import java.util.Collection;

/**
 * 弱引用列表 <br>
 * 
 */
public class WeakArrayList<T> extends AbstractList<T> {
	private static final long					serialVersionUID	= 2601162363164961860L;
	private static final Object					NULL_VALUE			= new Object();
	private final transient ReferenceQueue<T>	queue;
	private Object[]							data;
	private int									size;
	private boolean								enquedElement;

	@SuppressWarnings("unchecked")
	private static <T> T maskNull(T value) {
		return (T) (value == null ? WeakArrayList.NULL_VALUE : value);
	}

	private static <T> T unmaskNull(T value) {
		return (value == WeakArrayList.NULL_VALUE ? null : value);
	}

	public WeakArrayList(int initialCapacity) {
		this.queue = new ReferenceQueue<T>();

		this.enquedElement = false;

		if (initialCapacity < 0) {
			throw new IllegalArgumentException("Illegal Capacity: "
					+ initialCapacity);
		}
		this.data = new Object[initialCapacity];
		this.size = 0;
	}

	public WeakArrayList() {
		this(10);
	}

	public WeakArrayList(Collection<? extends T> c) {
		this.queue = new ReferenceQueue<T>();

		this.enquedElement = false;

		this.data = new Object[c.size()];
		this.size = this.data.length;
		int i = 0;
		for (T t : c) {
			this.data[i] = this.createRef(t);
			++i;
		}
	}

	@SuppressWarnings("unchecked")
	public String toString() {
		StringBuffer buffer = new StringBuffer();

		for (int i = 0; i < this.size; ++i) {
			Object obj;
			Reference<T> ref = (Reference<T>) this.data[i];
			if (this.data[i] == null) {
				obj = null;
			} else {
				obj = ref.get();
			}
			buffer.append('{');
			buffer.append(obj == null ? null : obj.toString());
			buffer.append('}');
		}
		return buffer.toString();
	}

	@SuppressWarnings("unchecked")
	private Reference<T> createRef(T obj) {
		return new WeakReference(WeakArrayList.maskNull(obj), this.queue);
	}

	public void ensureCapacity(int minCapacity) {
		this.modCount += 1;
		int oldCapacity = this.data.length;
		if (minCapacity > oldCapacity) {
			Object[] oldData = this.data;
			int newCapacity = oldCapacity * 3 / 2 + 1;
			if (newCapacity < minCapacity) {
				newCapacity = minCapacity;
			}
			this.data = SpeedyKit.copyOf(oldData, newCapacity);
		}
	}

	public void trimToSize() {
		this.modCount += 1;
		int oldCapacity = this.data.length;
		if (this.size < oldCapacity) {
			this.data = SpeedyKit.copyOf(this.data, this.size);
		}
	}

	@SuppressWarnings("unchecked")
	public int expurge() {
		int j;
		while (this.queue.poll() != null) {
			this.enquedElement = true;
		}

		if (this.enquedElement) {
			j = 0;
			for (int i = 0; i < this.size; ++i) {
				Reference<T> ref = (Reference<T>) this.data[i];
				if (ref == null || ref.isEnqueued() || ref.get() == null) {
					if (ref != null) {
						ref.clear();
					}
					this.data[i] = null;
				} else {
					if (i != j) {
						this.data[j] = this.data[i];
						this.data[i] = null;
					}
					++j;
				}
			}
			this.enquedElement = false;
		} else {
			j = this.size;
		}

		while (this.queue.poll() != null) {
			this.enquedElement = true;
		}

		this.size = j;

		return this.size;
	}

	protected void assertRange(int index, boolean allowLast) {
		int csize = this.expurge();
		if (index < 0) {
			throw new IndexOutOfBoundsException("invalid negative value: "
					+ Integer.toString(index));
		}
		if (allowLast && index > csize) {
			throw new IndexOutOfBoundsException("index>" + csize + ": "
					+ Integer.toString(index));
		}
		if (!allowLast && index >= csize) {
			throw new IndexOutOfBoundsException("index>=" + csize + ": "
					+ Integer.toString(index));
		}
	}

	public int size() {
		return this.expurge();
	}

	@SuppressWarnings("unchecked")
	public T get(int index) {
		Object value;
		do {
			this.assertRange(index, false);
			value = ((Reference<T>) this.data[index]).get();
		} while (value == null);
		return (T) WeakArrayList.unmaskNull(value);
	}

	@SuppressWarnings("unchecked")
	public T set(int index, T element) {
		Object oldValue;
		Reference<T> ref;
		do {
			this.assertRange(index, false);
			ref = (Reference<T>) this.data[index];
			oldValue = ref.get();
		} while (oldValue == null);
		ref.clear();
		this.data[index] = this.createRef(element);
		this.modCount += 1;
		return (T) WeakArrayList.unmaskNull(oldValue);
	}

	public void add(int index, T element) {
		this.assertRange(index, true);
		this.ensureCapacity(this.size + 1);
		System.arraycopy(this.data, index, this.data, index + 1, this.size
				- index);
		this.data[index] = this.createRef(element);
		this.size += 1;
		this.modCount += 1;
	}

	@SuppressWarnings("unchecked")
	public T remove(int index) {
		Object oldValue;
		Reference<T> ref;
		do {
			this.assertRange(index, false);
			ref = (Reference<T>) this.data[index];
			oldValue = ref.get();
		} while (oldValue == null);
		ref.clear();
		System.arraycopy(this.data, index + 1, this.data, index, this.size
				- index - 1);
		this.data[(this.size - 1)] = null;
		this.size -= 1;
		this.modCount += 1;
		return (T) WeakArrayList.unmaskNull(oldValue);
	}

	public static void main(String[] args) {
		Object a = new Object();
		WeakArrayList<Object> list = new WeakArrayList<Object>();
		for (int i = 0; i < 100000; i++) {
			list.add(a);
		}
		int size = list.size();
		System.out.println(size);
		a = null;
		while (list.size() == size) {
			System.gc();
		}
		System.out.println(list.size());
	}
}
分享到:
评论

相关推荐

    java中ArrayList 、LinkList区别.doc

    在Java编程语言中,ArrayList和LinkedList都是集合框架中两种重要的数据结构,它们...在实际开发中,还可以结合ArrayList和LinkedList的特性,利用Java集合框架中的其他数据结构,如HashSet或HashMap,来优化代码性能。

    Java中ArrayList和LinkedList区别 时间复杂度 与空间复杂度1

    在 Java 中,ArrayList 和 LinkedList 是两种常用的集合类,它们各自具有不同的特性和适用场景,主要体现在数据结构、访问效率和操作性能上。 1. 数据结构: - ArrayList 实现了一个动态数组,它内部是一个 Object...

    Java中List、ArrayList、Vector及map、HashTable、HashMap分别的区别.

    Java中的容器类是Java...对于内存效率和弱引用的需求,WeakHashMap是一个不错的选择。在实际应用中,通常推荐使用非同步的实现,如ArrayList和HashMap,因为它们的性能更高,然后根据需要在多线程场景下添加同步机制。

    深入arraylist,linkedlist,hashmap,hashset源码(2012/3/18)

    在Java编程语言中,ArrayList、LinkedList、HashMap和HashSet是四个非常重要的集合类,它们分别代表了不同类型的数据结构。这篇文章将深入探讨这些类的源码,以帮助我们更好地理解和运用它们。 首先,ArrayList是一...

    第8讲 对比Vector、ArrayList、LinkedList有何区别1

    在Java集合框架中,Vector、ArrayList和LinkedList都是List接口的实现,它们提供了有序集合的功能,允许根据位置进行元素的添加、删除和查找。然而,它们在设计和性能上有着显著的区别。 首先,Vector是Java早期...

    2021最新Java面试题及答案V2.0.pdf

    Java中有四种引用类型,分别是强引用、软引用、弱引用和虚引用。强引用是通常的引用,只要强引用还存在,对象就不会被垃圾回收器回收;软引用用于描述一些有用但非必需的对象,只在内存不足时才会被回收;弱引用描述...

    数据结构(java版本)

    集合则提供了不重复元素的存储,包括接口如Set和List,以及其实现类如HashSet和ArrayList。 书中还会涵盖排序和查找算法,例如冒泡排序、选择排序、插入排序、快速排序、归并排序等,这些是所有程序员都应掌握的...

    2022年java语言-java语言程序设计.docx

    Java 集合类可以用于存储和操作大量数据,包括 ArrayList、LinkedList、HashSet 等。 * ArrayList:ArrayList 是一种可变长的数组,能够存储大量数据。 * LinkedList:LinkedList 是一种链式数据结构,能够提供高效...

    java基本集合类,java基本集合类

    本篇文章将详细讲解Java中的基本集合类ArrayList、LinkedList和Vector,以及HashSet和TreeSet。 1. ArrayList ArrayList是基于动态数组实现的集合类,它允许存储重复元素。默认初始容量为10,当添加元素超过容量时...

    java集合类的效率测试

    本测试着重探讨了Java集合类中的Set接口实现类(如HashSet)以及List接口实现类(如ArrayList和LinkedList)在进行增、删、改、查操作时的性能差异。 首先,我们来看ArrayList。ArrayList是一个基于数组实现的列表...

    Java基础教程PPT

    此外,PPT可能还会涵盖数组和集合框架,数组是存储固定数量相同类型元素的数据结构,而集合框架(如ArrayList、LinkedList、HashSet和HashMap等)提供了更灵活的数据存储和操作方式。 文件I/O操作也是基础教程的一...

    Java面试总结,Redis宕机数据丢失解决方案,看完这篇彻底明白了.docx

    * 软引用和弱引用是Java中的两个引用类型,用于解决内存泄漏的问题 六、Java学习方法和技巧 1. 按照专题进行学习 * 将学习内容按专题进行分类,例如Java基础、算法与编程、数据库等 2. 由基础到高级,由浅入深 ...

    01-Java基础知识面试题(2023最新版).pdf

    Java语言提供了集合框架,包括ArrayList类、LinkedList类、HashSet类和TreeSet类等。Java集合框架提供了多种数据结构,允许开发者存储和操作大量数据。 Java基础知识是Java开发人员必须掌握的基本技能。掌握Java...

    Java核心编程Java 课件ppt

    9. **集合框架**:学习ArrayList、LinkedList、HashSet、HashMap等集合类的用法,以及泛型的概念。 10. **多线程**:理解并发编程的基础,包括线程的创建(通过Thread类和实现Runnable接口),线程同步...

    实验05 Java集合.doc

    在实验中,我们使用了ArrayList和LinkedList这两个实现类。ArrayList基于动态数组,随机访问速度快,但在插入和删除元素时,特别是中间位置,效率较低。LinkedList则基于双向链表,插入和删除速度快,但随机访问慢。...

    JAVA架构知识库整理.pdf

    List接口的典型实现包括ArrayList和Vector,前者基于数组,后者在内部实现上与ArrayList相似,但提供了线程同步功能。Set接口的实现包括HashSet、TreeSet和LinkedHashSet,分别基于哈希表、二叉树和HashMap。Map接口...

    JAVA面试核心知识点整理.pdf

    Java引用类型分为强引用、软引用、弱引用和虚引用。强引用是常规引用,不会被GC回收;软引用是指对象还有用但非必须;弱引用的对象是可回收的;虚引用是对象回收跟踪机制。 GC分代收集算法与分区收集算法不同。分代...

    数据结构和Java集合框架

    Collection接口是所有单值容器的超接口,它的子接口有List(有序、可重复元素,如ArrayList和LinkedList)和Set(无序、不可重复元素,如HashSet和TreeSet)。List接口允许通过索引访问元素,并支持添加、删除和修改...

    java api中文/英文

    例如,集合框架是Java编程中非常重要的部分,它包括了List(如ArrayList和LinkedList)、Set(如HashSet和TreeSet)、Map(如HashMap和TreeMap)等接口和实现,这些容器类帮助我们组织和管理数据。 在实际开发中,...

    1_JAVA核心知识点整理.pdf

    - Java中有四种引用类型:强引用、软引用、弱引用和虚引用。 - 强引用不会被垃圾回收机制回收;软引用仅在内存不足时才会被回收;弱引用一旦可达性分析完成后即被回收;虚引用则是为了追踪对象被垃圾回收的活动。 ...

Global site tag (gtag.js) - Google Analytics