⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hashtree.java

📁 测试工具
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.jorphan.collections;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;

/**
 * This class is used to create a tree structure of objects. Each element in the
 * tree is also a key to the next node down in the tree. It provides many ways
 * to add objects and branches, as well as many ways to retrieve.
 * <p>
 * HashTree implements the Map interface for convenience reasons. The main
 * difference between a Map and a HashTree is that the HashTree organizes the
 * data into a recursive tree structure, and provides the means to manipulate
 * that structure.
 * <p>
 * Of special interest is the {@link #traverse(HashTreeTraverser)} method, which
 * provides an expedient way to traverse any HashTree by implementing the
 * {@link HashTreeTraverser} interface in order to perform some operation on the
 * tree, or to extract information from the tree.
 * 
 * @author Michael Stover (mstover1 at apache.org)
 * @see HashTreeTraverser
 * @see SearchByClass
 * @version $Revision: 571988 $ Updated on: $Date: 2007-09-02 15:19:10 +0100 (Sun, 02 Sep 2007) $
 */
public class HashTree implements Serializable, Map {
	// GetLoggerForClass() uses ClassContext, which
	// causes a Security violation in RemoteJMeterImpl
	// Currently log is only used by test code, so moved there.
	// N.B. Can still add logging, but would beed to use getLoggerFor() instead
	// private static Logger log =
	// LoggingManager.getLoggerForClass();

	/**
	 * Creates an empty new HashTree.
	 */
	public HashTree() {
		data = new HashMap();
	}

	/**
	 * Creates a new HashTree and adds the given object as a top-level node.
	 * 
	 * @param key
	 */
	public HashTree(Object key) {
		data = new HashMap();
		data.put(key, new HashTree());
	}

	/**
	 * The Map given must also be a HashTree, otherwise an
	 * UnsupportedOperationException is thrown. If it is a HashTree, this is
	 * like calling the add(HashTree) method.
	 * 
	 * @see #add(HashTree)
	 * @see java.util.Map#putAll(Map)
	 */
	public void putAll(Map map) {
		if (map instanceof HashTree) {
			this.add((HashTree) map);
		} else {
			throw new UnsupportedOperationException("can only putAll other HashTree objects");
		}
	}

	/**
	 * Exists to satisfy the Map interface.
	 * 
	 * @see java.util.Map#entrySet()
	 */
	public Set entrySet() {
		return data.entrySet();
	}

	/**
	 * Implemented as required by the Map interface, but is not very useful
	 * here. All 'values' in a HashTree are HashTree's themselves.
	 * 
	 * @param value
	 *            Object to be tested as a value.
	 * @return True if the HashTree contains the value, false otherwise.
	 * @see java.util.Map#containsValue(Object)
	 */
	public boolean containsValue(Object value) {
		return data.containsValue(value);
	}

	/**
	 * This is the same as calling HashTree.add(key,value).
	 * 
	 * @param key
	 *            to use
	 * @param value
	 *            to store against key
	 * @see java.util.Map#put(Object, Object)
	 */
	public Object put(Object key, Object value) {
		Object previous = data.get(key);
		add(key, value);
		return previous;
	}

	/**
	 * Clears the HashTree of all contents.
	 * 
	 * @see java.util.Map#clear()
	 */
	public void clear() {
		data.clear();
	}

	/**
	 * Returns a collection of all the sub-trees of the current tree.
	 * 
	 * @see java.util.Map#values()
	 */
	public Collection values() {
		return data.values();
	}

	/**
	 * Adds a key as a node at the current level and then adds the given
	 * HashTree to that new node.
	 * 
	 * @param key
	 *            key to create in this tree
	 * @param subTree
	 *            sub tree to add to the node created for the first argument.
	 */
	public void add(Object key, HashTree subTree) {
		add(key);
		getTree(key).add(subTree);
	}

	/**
	 * Adds all the nodes and branches of the given tree to this tree. Is like
	 * merging two trees. Duplicates are ignored.
	 * 
	 * @param newTree
	 */
	public void add(HashTree newTree) {
		Iterator iter = newTree.list().iterator();
		while (iter.hasNext()) {
			Object item = iter.next();
			add(item);
			getTree(item).add(newTree.getTree(item));
		}
	}

	/**
	 * Creates a new HashTree and adds all the objects in the given collection
	 * as top-level nodes in the tree.
	 * 
	 * @param keys
	 *            a collection of objects to be added to the created HashTree.
	 */
	public HashTree(Collection keys) {
		data = new HashMap();
		Iterator it = keys.iterator();
		while (it.hasNext()) {
			data.put(it.next(), new HashTree());
		}
	}

	/**
	 * Creates a new HashTree and adds all the objects in the given array as
	 * top-level nodes in the tree.
	 */
	public HashTree(Object[] keys) {
		data = new HashMap();
		for (int x = 0; x < keys.length; x++) {
			data.put(keys[x], new HashTree());
		}
	}

	/**
	 * If the HashTree contains the given object as a key at the top level, then
	 * a true result is returned, otherwise false.
	 * 
	 * @param o
	 *            Object to be tested as a key.
	 * @return True if the HashTree contains the key, false otherwise.
	 * @see java.util.Map#containsKey(Object)
	 */
	public boolean containsKey(Object o) {
		return data.containsKey(o);
	}

	/**
	 * If the HashTree is empty, true is returned, false otherwise.
	 * 
	 * @return True if HashTree is empty, false otherwise.
	 */
	public boolean isEmpty() {
		return data.isEmpty();
	}

	/**
	 * Sets a key and it's value in the HashTree. It actually sets up a key, and
	 * then creates a node for the key and sets the value to the new node, as a
	 * key. Any previous nodes that existed under the given key are lost.
	 * 
	 * @param key
	 *            key to be set up
	 * @param value
	 *            value to be set up as a key in the secondary node
	 */
	public void set(Object key, Object value) {
		data.put(key, createNewTree(value));
	}

	/**
	 * Sets a key into the current tree and assigns it a HashTree as its
	 * subtree. Any previous entries under the given key are removed.
	 * 
	 * @param key
	 *            key to be set up
	 * @param t
	 *            HashTree that the key maps to
	 */
	public void set(Object key, HashTree t) {
		data.put(key, t);
	}

	/**
	 * Sets a key and it's values in the HashTree. It sets up a key in the
	 * current node, and then creates a node for that key, and sets all the
	 * values in the array as keys in the new node. Any keys previously held
	 * under the given key are lost.
	 * 
	 * @param key
	 *            Key to be set up
	 * @param values
	 *            Array of objects to be added as keys in the secondary node
	 */
	public void set(Object key, Object[] values) {
		data.put(key, createNewTree(Arrays.asList(values)));
	}

	/**
	 * Sets a key and its values in the HashTree. It sets up a key in the
	 * current node, and then creates a node for that key, and set all the
	 * values in the array as keys in the new node. Any keys previously held
	 * under the given key are removed.
	 * 
	 * @param key
	 *            key to be set up
	 * @param values
	 *            Collection of objects to be added as keys in the secondary
	 *            node
	 */
	public void set(Object key, Collection values) {
		data.put(key, createNewTree(values));
	}

	/**
	 * Sets a series of keys into the HashTree. It sets up the first object in
	 * the key array as a key in the current node, recurses into the next
	 * HashTree node through that key and adds the second object in the array.
	 * Continues recursing in this manner until the end of the first array is
	 * reached, at which point all the values of the second array are set as
	 * keys to the bottom-most node. All previous keys of that bottom-most node
	 * are removed.
	 * 
	 * @param treePath
	 *            array of keys to put into HashTree
	 * @param values
	 *            array of values to be added as keys to bottom-most node
	 */
	public void set(Object[] treePath, Object[] values) {
		if (treePath != null && values != null) {
			set(Arrays.asList(treePath), Arrays.asList(values));
		}
	}

	/**
	 * Sets a series of keys into the HashTree. It sets up the first object in
	 * the key array as a key in the current node, recurses into the next
	 * HashTree node through that key and adds the second object in the array.
	 * Continues recursing in this manner until the end of the first array is
	 * reached, at which point all the values of the Collection of values are
	 * set as keys to the bottom-most node. Any keys previously held by the
	 * bottom-most node are lost.
	 * 
	 * @param treePath
	 *            array of keys to put into HashTree
	 * @param values
	 *            Collection of values to be added as keys to bottom-most node
	 */
	public void set(Object[] treePath, Collection values) {
		if (treePath != null) {
			set(Arrays.asList(treePath), values);
		}
	}

	/**
	 * Sets a series of keys into the HashTree. It sets up the first object in
	 * the key list as a key in the current node, recurses into the next
	 * HashTree node through that key and adds the second object in the list.
	 * Continues recursing in this manner until the end of the first list is
	 * reached, at which point all the values of the array of values are set as
	 * keys to the bottom-most node. Any previously existing keys of that bottom
	 * node are removed.
	 * 
	 * @param treePath
	 *            collection of keys to put into HashTree
	 * @param values
	 *            array of values to be added as keys to bottom-most node
	 */
	public void set(Collection treePath, Object[] values) {
		HashTree tree = addTreePath(treePath);
		tree.set(Arrays.asList(values));
	}

	/**
	 * Sets the nodes of the current tree to be the objects of the given
	 * collection. Any nodes previously in the tree are removed.
	 * 
	 * @param values
	 *            Collection of objects to set as nodes.
	 */
	public void set(Collection values) {
		clear();
		this.add(values);
	}

	/**
	 * Sets a series of keys into the HashTree. It sets up the first object in
	 * the key list as a key in the current node, recurses into the next
	 * HashTree node through that key and adds the second object in the list.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -