Java练习案例,Java项目实战,集合框架

本文详细介绍了Java中TreeMap类的实现,包括其内部结构、主要方法如put、remove、get、containsKey、containsValue等。此外,还展示了如何使用TreeMap的迭代器遍历和操作元素,以及如何通过getOrDefault方法获取默认值。文章通过示例代码演示了TreeMap的各种功能,帮助读者深入理解TreeMap的工作原理。
摘要由CSDN通过智能技术生成

public class TreeMap<K,V>{

public static abstract class AbstractCollection<E> implements Set<E>{}
public static abstract class AbstractSet<E> extends AbstractCollection<E>{}
public interface Iterator<E> {
	boolean hasNext() ;
	E next() ;
}
public interface Set <E>{
	Iterator<E> iterator() ;
} 
public interface Map<K,V> {
	
	interface Entry<K,V> {
		K getKey() ;
		V getValue() ;
	}
	V get (Object key) ;
	boolean containsKey(Object key) ;
	/**
	 * 返回指定键映射到的值,如果此映射不包含该键的映射,则返回{@code defaultValue}。
	 * @param key
	 * 指定的键
	 * @param defaultValue
	 * 如果此映射不包含该键的映射时要返回的值
	 * @return
	 */
	default V getOrDefault(Object key , V defaultValue) {
		V v ;
		return (( v = get(key)) != null || containsKey(key)) ? v : defaultValue ;
	}
}
public static abstract class AbstractMap<K,V> implements Map<K,V> , Cloneable{
	public static class SimpleImmutableEntry<K,V> implements Map.Entry<K, V>{
		private final K key ;
		private final V value ;
		public SimpleImmutableEntry (Map.Entry<? extends K, ? extends V> entry) {
			this.key = entry.getKey() ;
			this.value = entry.getValue() ;
		}
		public K getKey () {
			return key ;
		}
		public V getValue () {
			return value ;
		}
		public synchronized String toString() {
			return key + " " + value ;
		}
	}
	public abstract Set<Map.Entry<K,V>> entrySet() ;
	public synchronized String toString () {
		Iterator<Map.Entry<K, V>> i = entrySet().iterator() ;
		if (!i.hasNext())
			return "{}" ;
		StringBuilder s = new StringBuilder() ;
		s.append("{") ;
		for( ; ; ) {
			Map.Entry<K, V> e = i.next() ;
			K key = e.getKey() ;
			V value = e.getValue() ;
			s.append(key == this ? "(this Map)" : key.toString()) ;
			s.append("=") ;
			s.append(value == this ? "(this Map)" : value.toString()) ;
			if (!i.hasNext())
				return s.append("}").toString() ;
			s.append(',').append(' ') ;
		}
	}
}
public static final class Objects {
	
	public static <T> T nonNull ( T obj) {
		if ( obj == null) 
			throw new NullPointerException() ;
		return obj ;
	}
}
public interface Comparator <T> {
	int compare ( T o1 , T o2) ;
}
public static class TreeMap1<K,V> extends AbstractMap<K,V>{
	/**
	 * 删除此映射中的所有映射。此调用返回后,映射将为空。
	 */
	public void clear() {
		modCount++ ;
		size = 0 ;
		root = null ;
	}
	/**
	 * 返回此映射中的键值映射数。
	 * @return
	 */
	public int size() {
		return size ;
	}
	/**
	 * 删除节点p,然后重新平衡树。
	 * @param p
	 * 要删除的节点
	 */
	private void deleteEntry(Entry<K,V> p) {
		modCount++ ;
		size-- ;
		/*如果是严格内部的,则将继任者的元素复制到p,然后使p指向继任者。*/
		if (p.left != null && p.right != null) {
			Entry<K,V> s = successor(p) ;
			p.key = s.key ;
			p.value = s.value ;
			p = s ;
		}
		/*在替换节点(如果存在)启动修复*/
		Entry<K,V> replacement = (p.left != null ? p.left : p.right) ;
		if ( replacement != null) {
			/*将替换链接到父级*/
			replacement.parent = p.parent ;
			if (p.parent == null )
				root = replacement ;
			else if (p == p.parent.left)
				p.parent.left = replacement ;
			else
				p.parent.right = replacement ;
			/*清空链接,这样它们就可以被FixAfterDelete使用了。*/
			p.left = p.right = p.parent = null ;
		}else if (p.parent == null )
			root = null ;
		else {/*没有孩子。将self用作幻影替换并取消链接。*/
			if (p.parent != null ) {
				if (p == p.parent.left)
					p.parent.left = null ;
				else if (p == p.parent.left)
					p.parent.right = null ;
				p.parent = null ;
			}
		}
	}
	/**
	 * 从树映射中删除此键的映射(如果存在)。
	 * @param key 
	 * 应删除其映射的键
	 * @return 
	 * 指定的键关联上的一个值
	 */
	public V remove(Object key) {
		Entry<K,V> p = getEntry(key) ;
		if ( p == null) 
			return null ;
		V oldValue = p.value ;
		deleteEntry(p) ;
		return oldValue ;
	}
	/**
	* 与指定键关联的上一个值,如果该键没有映射,则为null
	* @param key
	* 与指定值关联的键
	* @param value
	* 要与指定键关联的值
	* @return
	* 如果指定的键没有被映射 , 就返回 value ,否则返回指定的键关联上的一个值,该方法无法替换原有值
	*/
	public V putIfAbsent(K key , V value) {
		return put(key , value , false) ;
	}
	/**
	 * 返回指定键映射到的值,如果此映射不包含该键的映射,则返回{@code null}
	 */
	public V get(Object key) {
		Entry<K,V> p = getEntry(key) ;
		return ( p == null ? null : p.value) ;
	}
	/**
	 * 测试两个值是否相等。与o1不同。等于(o2),只是因为它能正确地处理{@code null}o1。
	 * @param o1
	 * @param o2
	 * @return
	 */
	private static final boolean valEquals(Object o1 , Object o2) {
		return (o1 == null ? o2 == null : o1.equals(o2)) ;
	}
	/**
	 * 返回树映射中的第一个条目(根据树映射的键排序函数)。如果树映射为空,则返回null。
	 * @return
	 */
	private final Entry<K,V> getFirstEntry () {
		Entry<K,V> p = root ;
		if ( p != null ) 
			while ( p.left != null )
				p = p.left ;
		return p ;
	}
	/**
	 * 如果此映射将一个或多个键映射到指定值,则返回{@code true}。
	 * @param value
	 * 要测试其在该地图中的存在的值
	 * @return
	 */
	/*156*/
	public boolean containsValue (Object value) {
		for (Entry<K,V> e = getFirstEntry() ; e != null ; e = successor(e) ) {
			if (valEquals (value , e.value )) 
				return true ;
		}
		return false ;
	}
	/**
	 * 使用comparator的getEntry版本。与getEntry分离以获得性能。
	 * (对于大多数不太依赖比较器性能的方法来说,这是不值得的,但在这里是值得的。)
	 * @param key
	 * @return
	 */
	private final Entry<K,V> getEntryUsingComparator (Object key) {
		@SuppressWarnings("unchecked")
		K k = (K)key ;
		Comparator<? super K> c = comparator ;
		if (c != null) {
			Entry<K,V> p = root ;
			while (p != null ) {
				int cmp = c.compare(k,p.key) ;
				if (cmp < 0 )
					p = p.left ;
				else if (cmp > 0 )
					p = p.right ;
				else
					return p ;
			}
		}
		return null ;
	}
	/**
	 * 返回给定键的映射项,如果映射不包含该键的项,则返回{@code null}
	 * @param key
	 * @return
	 */
	private final Entry<K,V> getEntry (Object key) {
		if ( comparator != null )
			return getEntryUsingComparator(key) ;
		Objects.nonNull(key) ;
		@SuppressWarnings("unchecked")
		Comparable<? super K> k = (Comparable<? super K>) key ;
		Entry<K,V> p = root ;
		while(p != null) {
			int cmp = k.compareTo(p.key) ;
			if ( cmp < 0 )
				p = p.left ;
			else if ( cmp > 0 ) 
				p = p.right ;
			else 
				return p ;
		}
		return null ;
	}
	/**
	 * 如果此映射包含指定键的映射,则返回{@code true}。
	 */
	public boolean containsKey ( Object key ) {
		return getEntry(key) != null;
	}
	/**
	 * 获取与指定键对应的项;如果不存在这样的条目,则返回大于指定密钥的最小密钥的条目;
	 * 如果不存在这样的条目(即树中最大的键小于指定的键),则返回{@code null}。
	 * @param key
	 * @return
	 */
	private final Entry<K,V> getCeilingEntry (K key) {
		Entry<K,V> p = root ;
		while ( p != null) {
			int cmp = compare(key , p.key) ;
			if ( cmp < 0 ) {
				if ( p.left != null )
					p = p.left ; 
				else
					return p ;
			}else if ( cmp > 0 ) {
				if ( p .right != null) {
					p = p.right ;
				} else {
					Entry<K,V> parent = p.parent ;
					Entry<K,V> ch = p ;
					while ( parent != null && ch == parent.right) {
						ch = parent ;
						parent = parent.parent ;
					}
					return parent ;
				}
			}else {
				return p ;
			}
				
		}
		return null ;
	}
	/**
	 * 为entry返回SimpleImutableEntry,如果为null,则返回null
	 * @param <K>
	 * @param <V>
	 * @param e
	 * @return
	 */
	private static <K,V> Map.Entry<K, V> exportEntry (Entry<K,V> e) {
		return (e == null) ? null : new AbstractMap.SimpleImmutableEntry<>(e) ;
	}
	public Map.Entry<K, V> ceilingEntry (K key) {
		return exportEntry( getCeilingEntry(key)) ;
	}
	public Object clone() {
		TreeMap1<?,?> clone ;
		try {
			clone = (TreeMap1<?,?>)super.clone() ;
		} catch ( CloneNotSupportedException e ) {
			throw new InternalError(e) ;
		}
		return clone ;
	}
	/**
	 * 返回指定项的后续项,如果没有,则返回null。
	 * @param <K>
	 * @param <V>
	 * @param t
	 * 节点
	 * @return
	 */
	private static <K,V> Entry<K, V> successor (Entry<K,V> t) {
		if( t == null )
			return null ;
		else if ( t.right != null ) {
			Entry<K,V> p = t.right ;
			while( p.left != null )
				p = p.left ;
			return p ;
		}else {
			Entry<K,V> p = t.parent ;
			Entry<K,V> ch = t ;
			while( p != null && ch == p.right ) {
				ch = p ;
				p = p.parent ;
			}
			return p ;
		}
	}
	public abstract class PrivateEntry<T> implements Iterator<T>{
		
		PrivateEntry(Entry<K,V> first) {
			expectedModCount = modCount ;
			lastReturned = null ;
			next = first ;
		}
		Entry<K,V> next ;
		Entry<K,V> lastReturned ;
		int expectedModCount ;
		
		public final boolean hasNext() {
			return next != null ;
		}
		final Entry<K,V> nextEntry() {
			Entry<K,V> e = next ;
			if ( e == null)
				throw new NoSuchElementException() ;
			if ( modCount != expectedModCount)
				throw new ConcurrentModificationException() ;
			next = successor(e) ;
			lastReturned = e ;
			return e ;
		}
	}
	public final class EntryIterator extends PrivateEntry<Map.Entry<K, V>>{
		EntryIterator(Entry<K,V> first) {
			super(first) ;
		}
		public Map.Entry<K, V> next () {
			return nextEntry() ;
		}
	}
	/*295*/
	public class EntrySet extends AbstractSet<Map.Entry<K, V>>{
		public Iterator<Map.Entry<K, V>> iterator() {
			return new EntryIterator(getFirstEntry()) ;
		}
	}
	private transient EntrySet entrySet ;
	/*397*/
	public Set<Map.Entry<K, V>> entrySet() {
		EntrySet es = entrySet ;
		return( es != null) ? es : ( entrySet = new EntrySet()) ;
	}
	private void addEntry( K key , V value , Entry<K,V> parent , boolean addToLeft) {
		Entry<K,V> e = new Entry<>(key, value, parent) ;
		if (addToLeft) 
			parent.left = e ;
		else
			parent.right = e ;
		size++ ;
		modCount++ ;
	}
	public TreeMap1 () {
		comparator = null ;
	}
	static final class Entry<K,V> implements Map.Entry<K,V>{
		K key ; V value ; Entry<K,V> parent ;
		Entry<K,V> left ; Entry<K,V> right ;
		Entry(K key , V value ,Entry<K,V> parent) {
			this.key = key ;
			this.value = value ;
			this.parent = parent ;
		}
		public synchronized String toString() {
			return key + " " + value ;
		}
		public K getKey() {
			return key ;
		}
		public V getValue() {
			return value ;
		}
	}
	private final Comparator<? super K> comparator ;
	@SuppressWarnings("unchecked")
	private final int compare ( Object k1 , Object k2) {
		return comparator == null ? ((Comparable<? super K>)k1).compareTo((K)k2)  : comparator.compare((K)k1, (K)k2) ;
	}
	private transient int size = 0 ;
	private transient int modCount ;
	/*339*/
	private void addEntry(K key , V value ) {
		compare(key , key) ;
		root = new Entry<>(key , value , null) ;
		size++ ;
		modCount++ ;
	}
	private transient Entry<K,V> root ;
	/*346*/
	public V put(K key , V value , boolean repla) {
		Entry<K,V> t = root ;
		if ( t == null ) {
			addEntry(key , value) ;
			return value ;
		}
		Entry<K,V> parent ; int cmp ;
		Comparator<? super K> cpr = comparator ;
		if ( cpr != null) {
			Objects.nonNull(key) ;
			do {
				parent = t ;
				cmp = cpr.compare(key , t.key) ;
				if ( cmp < 0 )
					t = t.left ;
				else if ( cmp > 0 )
					t = t.right ;
				else {
					V oldValue = t.value ;
					if ( repla || oldValue == null) 
						t.value = value ;
					return oldValue ;
				}
			} while( t != null ) ;
		} else {
			Objects.nonNull(key) ;
			@SuppressWarnings("unchecked")
			Comparable<? super K > k = (Comparable<? super K>) key ;
			do {
				parent = t ;
				cmp = k.compareTo(t.key) ;
				if ( cmp < 0 )
					t = t.left ;
				else if ( cmp > 0 )
					t = t.right ;
				else {
					V oldValue = t.value ;
					if ( repla || oldValue == null) 
						t.value = value ;
					return oldValue ;
				}
			} while( t != null ) ;
		}
		addEntry(key , value , parent , cmp < 0 ) ;
		return null ;
	}
}
public synchronized String toString() {
	return tree.toString() ;
}
private transient TreeMap1<K,V> tree ;
public TreeMap() {
	this.tree = new TreeMap1<>() ;
}
/**
 * 将指定的值与此映射中的指定键相关联。如果映射之前包含密钥的映射,则旧的值被替换。
 * @param key
 * 与指定值关联的键
 * @param value
 * 要与指定键关联的值
 * @return
 * 与{@code key}关联的上一个值,如果{@code key}没有映射,则为{@code null}。
 */
public V put(K key , V value ) {
	return tree.put(key, value,true) ;
}
/**
 * 返回此{@code TreeMap}实例的浅层副本。(键和值本身不会被克隆。
 */
public Object clone () {
	return tree.clone() ;
}
/**
 * 如果指定的键为null,并且此映射使用自然排序,或者其比较器不允许null键,
 * 则ClassCastException{@inheritDoc}@将抛出NullPointerException
 * @param key
 * 指定的键
 * @return
 */
public Map.Entry<K, V> ceilingEntry( K key) {
	return tree.ceilingEntry(key) ;
}
/**
 * 如果此映射包含指定键的映射,则返回{@code true}。
 */
public boolean containsKey (Object key) {
	return tree.containsKey(key) ;
}
/**
 * 如果此映射将一个或多个键映射到指定值,则返回{@code true}。
 * @param value
 * 要测试其在该地图中的存在的值
 * @return
 */
public boolean containsValue (Object value) {
	return tree.containsValue(value) ;
}
/**
 * 返回指定键映射到的值,如果此映射不包含该键的映射,则返回{@code null}
 * @param key
 * 指定的键
 * @return
 */
public V get(Object key) {
	return tree.get(key) ;
}
/**
 * 返回指定键映射到的值,如果此映射不包含该键的映射,则返回{@code defaultValue}。
 * @param key
 * 指定的键
 * @param defaultValue
 * 如果此映射不包含该键的映射时要返回的值
 * @return
 */
public V getOrDefault(Object key , V defaultValue) {
	return tree.getOrDefault(key, defaultValue) ;
}
/**
 * 与指定键关联的上一个值,如果该键没有映射,则为null,该方法无法替换原有值
 * @param key
 * 与指定值关联的键
 * @param value
 * 要与指定键关联的值
 * @return
 */
public V putIfAbsent(K key , V value) {
	return tree.putIfAbsent(key, value) ;
}
/**
 * 从树映射中删除此键的映射(如果存在)。
 * @param key
 * 应删除其映射的键
 * @return
 */
public V remove(K key) {
	return  tree.remove(key) ;
}
/**
 * 返回此映射中的键值映射数。
 * @return
 */
public int size() {
	return tree.size() ;
}
/**
 * 删除此映射中的所有映射。此调用返回后,映射将为空。
 */
public void clear() {
	 tree.clear() ;
}

}
集合方法的调用 :
TreeMap<Integer , Object > tree = new TreeMap<Integer ,Object >() ;
for(int y = 0 ; y < 10 ; y++ ) {
/将指定的值与此映射中的指定键相关联。如果映射之前包含键的映射,则替换旧值。/
tree.put(y , “fkljflkjdsflkjkjf” + y) ;
}
/返回与大于或等于给定键的最小键关联的键值映射,如果没有这样的键,则返回null。/
System.out.println(tree.ceilingEntry(5) );
/如果此映射包含指定密钥的映射,则返回true。/
System.out.println(tree.containsKey(30));
/如果此映射将一个或多个键映射到指定值,则返回true。/
System.out.println(tree.containsValue(“fkljflkjdsflkjkjf1”));
/返回指定键映射到的值,如果此映射不包含该键的映射,则返回null。/
System.out.println(tree.get(4));
/返回指定键映射到的值,如果此映射不包含该键的映射,则返回defaultValue。/
System.out.println(tree.getOrDefault(3,“jkfhk324654msdfjh3”));
/如果指定的键尚未与值关联(或映射为null),则将其与给定值关联并返回null,否则返回当前值。/
System.out.println(tree.putIfAbsent(1,“dkjgkjdfgk10”));
/从树映射中删除此键的映射(如果存在)/
System.out.println(tree.remove(1));
/仅当指定项当前映射到指定值时,才删除该项/
System.out.println(tree.remove(5, “kjfhkajsh9823437”));
/返回此映射中的键值映射数。/
System.out.println(tree.size());

	System.out.println(tree.clone());
	tree.clear();
	System.out.println() ;

加粗样式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值