it's an algo from internet about Red-Black BST Java implementation. I am confused about the variable named val in this program. Here is the code:
package tools;
public class redBlack2 {
private static final boolean RED = true;
private static final boolean BLACK = false;
private Node root;
public redBlack2() {}
private class Node {
private int key;
private int val;
private Node left, right;
private boolean color;
public Node(int key, int val, boolean color) {
this.key = key;
this.val = val;
this.color = color;
}
}
private boolean isRed(Node x) {
if (x == null) return false;
return x.color == RED;
}
public int get(int key) {
return get(root, key);
}
private int get(Node x, int key) {
while (x != null) {
if (key < x.key) x = x.left;
else if (key > x.key) x = x.right;
else return x.val;
}
System.out.println("There is no such key.");
return 0;
}
public boolean contains(int key) {
return get(key) != 0;
}
public void put(int key, int val) {
root = put(root, key, val);
root.color = BLACK;
}
private Node put(Node h, int key, int val) {
if (h == null) return new Node(key, val, RED);
if (key<h.key) h.left = put(h.left, key, val);
else if (key>h.key) h.right = put(h.right, key, val);
else if (key == h.key) h.val = val;
if (isRed(h.right) && !isRed(h.left)) h = rotateLeft(h);
if (isRed(h.left) && isRed(h.left.left)) h = rotateRight(h);
if (isRed(h.left) && isRed(h.right)) flipColors(h);
return h;
}
private Node rotateRight(Node h) {
Node x = h.left;
h.left = x.right;
x.right = h;
x.color = x.right.color;
x.right.color = RED;
return x;
}
private Node rotateLeft(Node h) {
Node x = h.right;
h.right = x.left;
x.left = h;
x.color = x.left.color;
x.left.color = RED;
return x;
}
private void flipColors(Node h) {
h.color = !h.color;
h.left.color = !h.left.color;
h.right.color = !h.right.color;
}
public static void main(String[] args) {
redBlack2 r = new redBlack2();
r.put(34,1);
r.put(23,2);
r.put(65,3);
r.put(73, 4);
System.out.print(r.get(73));
}
}
is that just a mark we give to the number we put inside the Tree? then don't we already have key as a mark? why we still need variable val?
Yes, you're right, it's just like a mark. We can indeed implement this algorithm with just one variable, i.e., key. In this algo, val is something that is being stored as a type of data for which we need to keep track.
For example consider this
You have several numbered boxes like 34, 23, 65, 73 and you want to
implement RB Tree operations on them. So these number on boxes
resembles the key in your algorithm.
Now consider each box contains a number of balls in it. These balls
can be seen as a data which is stored inside the box and you need to
keep a track of it. So this can be considered as val.
You can even go a step further and keep a track of several things that are inside a box by changing the data-type of val to List or Map or even user-defined objects. It will still work the same way.
In this implementation, this data structure acts like a Map, which means it maps keys to values. That val is a common abbreivation of value, which is quite self-explainatory. It could be of any type existing in Java, be it primitive or reference.
Related
There is only one difference between the correct answer and my answer, and that is, I am traversing the entire tree instead of comparing the target with the node value and eliminating one-half of the tree in each recursion. Please help me with the explanation. Thanks.
My code:
import java.util.*;
class Program {
public static int findClosestValueInBst(BST tree, int target) {
//int closest = Integer.MAX_VALUE;
// int val = 0;
int vl = findClosestValueInBst1(tree, target, tree.value);
return vl;
}
public static int findClosestValueInBst1(BST tree, int target, int val) {
// System.out.println((closest + " " + Math.abs(tree.value - target)));
//c = closest;
if(( Math.abs(target - tree.value)) < ( Math.abs(target - val))){
System.out.println(val);
val = tree.value;
}
if(tree.left != null){
return findClosestValueInBst1(tree.left, target, val);
}
if(tree.right != null){
return findClosestValueInBst1(tree.right, target, val);
}
return val;
}
static class BST {
public int value;
public BST left;
public BST right;
public BST(int value) {
this.value = value;
}
}
}
Question tree- Root =10,
Nodes-> [10,15,22,13,14,5,5,2,1],
Target: 12,
My output: 10,
Correct answer: 13,
import java.util.*;
class Program {
public static int findClosestValueInBst(BST tree, int target) {
//int closest = Integer.MAX_VALUE;
// int val = 0;
int vl = findClosestValueInBst1(tree, target, tree.value);
return vl;
}
public static int findClosestValueInBst1(BST tree, int target, int val) {
// System.out.println((closest + " " + Math.abs(tree.value - target)));
//c = closest;
if(( Math.abs(target - tree.value)) < ( Math.abs(target - val))){
System.out.println(val);
val = tree.value;
}
if( target < tree.value && tree.left != null){
return findClosestValueInBst1(tree.left, target, val);
} else
if(target > tree.value && tree.right != null){
return findClosestValueInBst1(tree.right, target, val);
} else
return val;
}
static class BST {
public int value;
public BST left;
public BST right;
public BST(int value) {
this.value = value;
}
}
}
The tree looks like this:
10
/\
5 15
/ /\
2 13 22
/ \
1 14
Your code is not actually traversing the whole tree. This code:
if(tree.left != null){
return findClosestValueInBst1(tree.left, target, val);
}
if(tree.right != null){
return findClosestValueInBst1(tree.right, target, val);
}
return val;
checks the left subtree if it exists (and ignores the right subtree). Otherwise, check the right subtree if it exists. Otherwise stop the recursion. This is because once you reach a return statement, the entire method stops there, and the lines after that do not get executed.
So your code always prefers the left subtree without taking into account what number the node actually stores. So right off the bat, you went to the wrong direction - you are looking for 13, and the current node is 10, a closer value is gotta be bigger than 10, i.e. in the right subtree.
An implementation that actually traverses the whole tree would be something like:
public static int findClosestValueInBst(BST tree, int target) { // no need for the val argument!
int leftClosest = tree.value;
int rightClosest = tree.value;
if(tree.left != null){
leftClosest = findClosestValueInBst1(tree.left, target);
}
if(tree.right != null){
rightClosest = findClosestValueInBst1(tree.right, target);
}
if (target - leftClosest < rightClosest - target) {
return leftClosest;
} else {
return rightClosest;
}
}
But why bother when you can do it more quickly? :)
In my case, I want to create a binary tree by taking the depth as the input.
class BTreeNode<T> {
BTreeNode<T> left,right;
int index;
T value;
BTreeNode(T value, int index){
this.index = index;
this.value = value;
}
}
class Tree<T> {
int depth;
BTreeNode<T> root;
public static <K> eTree<K> create(int depth){
if(depth > 0) {
Tree<K> newtree = new SparseTree<>();
newtree.root = new BTreeNode<>(null,0);
newtree.addLevel(newtree.root, 0, depth);
return newtree;
}
else {
throw new Error();
}
}
private void addLevel(BTreeNode<T> node, int depth, int deepest){
if(depth == deepest - 1) {
return;
}
// ???
node.left = new BTreeNode<>(node.value,node.index+1);
node.right = new BTreeNode<>(node.value,node.index+2);
addLevel(node.left,depth + 1,deepest);
addLevel(node.right,depth + 1,deepest);
}
}
Then, I want to add an index for every node in the tree accordingly. For example, for a tree with 7 nodes (depth == 3), the index for every node will be 0 1 2 3 4 5 6.
What I can do in my code to achieve this? I did several attempts but all failed. Any suggestions? Thanks!
because
index_left = 2*index_father+1
index_right = 2*index_father+2
you can do something like this
private void addLevel(BTreeNode<T> node, int depth, int deepest, int index){
if(depth == deepest - 1) {
return;
}
node.left = new BTreeNode<>(node.value,index*2+1);
node.right = new BTreeNode<>(node.value,index*2+2);
addLevel(node.left,depth + 1,deepest, index*2+1);
addLevel(node.right,depth + 1,deepest,index*2+2);
}
I am making a trie data structure. I want to find the number of occurrences of specific word in that trie e.g. if the word 'similar' is coming four times in a trie, the program should give the output of that word as 4. Can someone guide me in the right direction? Here is my code of class which is telling the index of that specific word.
public class TST<Value> {
private int N; // size
private Node root; // root of TST
private class Node {
private char c; // character
private Node left, mid, right; // left, middle, and right subtries
private Value val; // value associated with string
}
// return number of key-value pairs
public int size() {
return N;
}
public boolean contains(String key) {
return get(key) != null;
}
public Value get(String key) {
if (key == null) throw new NullPointerException();
if (key.length() == 0) throw new IllegalArgumentException("key must have length >= 1");
Node x = get(root, key, 0);
if (x == null) return null;
return x.val;
}
// return subtrie corresponding to given key
private Node get(Node x, String key, int d) {
if (key == null) throw new NullPointerException();
if (key.length() == 0) throw new IllegalArgumentException("key must have length >= 1");
if (x == null) return null;
char c = key.charAt(d);
if (c < x.c) return get(x.left, key, d);
else if (c > x.c) return get(x.right, key, d);
else if (d < key.length() - 1) return get(x.mid, key, d+1);
else return x;
}
public void put(String s, Value val) {
if (!contains(s)) N++;
root = put(root, s, val, 0);
}
private Node put(Node x, String s, Value val, int d) {
char c = s.charAt(d);
if (x == null) {
x = new Node();
x.c = c;
}
if (c < x.c) x.left = put(x.left, s, val, d);
else if (c > x.c) x.right = put(x.right, s, val, d);
else if (d < s.length() - 1) x.mid = put(x.mid, s, val, d+1);
else x.val = val;
return x;
}
I'm new in Java. I'm trying to obtain the average depth tree depth. I already have the number of nodes. I just need each node's depth. I have a method to obtain the height of the tree. I'm thinking if I could use this method and reverse it to obtain the depth of every node. But I don't know how to specify the node in the method.
Do you guys have any advice for specifying the nodes one by one in the method?
Right now my method take a tree type as parameter
PS: English is not my native language. Sorry for any confusion
import java.util.*;
public class HuffmanCode {
int numberOfNode = 1;
int height;
String fullcode = "";
String realcode = "";
// input is an array of frequencies, indexed by character code
public HuffmanTree createTree(int[] charFreqs) {
PriorityQueue<HuffmanTree> trees = new PriorityQueue<HuffmanTree>();
// initially, we have a forest of leaves
// one for each non-empty character
for (int x = 0; x < charFreqs.length; x++) {
if (charFreqs[x] > 0)
trees.offer(new HuffmanLeaf(charFreqs[x], (char) x));
}
/*
* Step 2 in Huffman coding While loop to remove 2 nodes with the
* highest priority(lowest probability)
*/
while (trees.size() > 1) {
// Poll the two nodes with least frequency
HuffmanTree a = trees.poll();
HuffmanTree b = trees.poll();
// put into new node and re-insert into queue
trees.offer(new HuffmanNode(a, b));
numberOfNode++;
}
return trees.poll();
}
public void printResults(HuffmanTree tree, StringBuffer prefix) {
if (tree instanceof HuffmanLeaf) {
HuffmanLeaf leaf = (HuffmanLeaf) tree;
// print out character, frequency, and code for this leaf (which is
// just the prefix)
System.out.println(leaf.value + "\t" + leaf.frequency + "\t" + prefix);
encodedInput(prefix);
for (int x = 0; x < leaf.frequency; x++) {
realcode = realcode + prefix;
}
} else if (tree instanceof HuffmanNode) {
HuffmanNode node = (HuffmanNode) tree;
numberOfNode++;
// move left
prefix.append('0');
printResults(node.left, prefix);
prefix.deleteCharAt(prefix.length() - 1);
// move right
prefix.append('1');
printResults(node.right, prefix);
prefix.deleteCharAt(prefix.length() - 1);
height = findHeight(node);
}
}
public void encodedInput(StringBuffer prefix) {
fullcode = fullcode + " , " + prefix;
}
public int findHeight(HuffmanTree tree) {
if (tree == null) {
return -1;
}
if (tree instanceof HuffmanLeaf) {
return 0;
} else if (tree instanceof HuffmanNode) {
int left = findHeight(((HuffmanNode) tree).left);
int right = findHeight(((HuffmanNode) tree).right);
if (left > right) {
return left + 1;
} else {
return right + 1;
}
} else {
return -1; // does not happen, you might want to raise exception.
}
}
public void printQueue(PriorityQueue<HuffmanTree> pq) {
while (pq.size() > 0) {
System.out.println(pq.poll());
}
}
}
Other class I have:
class HuffmanNode extends HuffmanTree {
public HuffmanTree left;
public HuffmanTree right;
public HuffmanNode(HuffmanTree left, HuffmanTree right) {
super(left.frequency + right.frequency);
this.left = left;
this.right = right;
}
}
class HuffmanLeaf extends HuffmanTree {
public char value; // the character this leaf represents
public HuffmanLeaf(int frequency, char value) {
super(frequency);
this.value = value;
}
}
public class HuffmanTree implements Comparable<HuffmanTree> {
public int frequency; // the frequency of this tree
public HuffmanTree(int frequency) {
this.frequency = frequency;
}
public int compareTo(HuffmanTree tree) {
return frequency - tree.frequency;
}
}
This code maybe help you. you can traverse from root and calculate sum of depth.
public int sum(HuffmanTree tree,int currentDepth) {
if (tree == null) {
return -1;
}
if (tree instanceof HuffmanLeaf) {
return currentDepth;
} else if (tree instanceof HuffmanNode) {
int left = sum(((HuffmanNode) tree).left , currentDepth+1);
int right = sum(((HuffmanNode) tree).right, currentDepth+1);
return left+right;
} else {
return -1; // does not happen, you might want to raise exception.
}
}
So I need a 2-dimensional ConcurrentHashMap.
It has to be as blazing fast as possible, as I'm going to be adding to and updating its values extremely frequently. It's in a multithreaded application, hence the choice to use ConcurrentHashMap instead of just HashMap.
Both the "x" and "y" indices are integers with a known range (0 through 40,000,000).
What I need to know is: What's the most efficient way to implement this so it'll be as speedy as possible? The most obvious route is to do a literal 2-D hashmap:
ConcurrentHashMap<Integer, ConcurrentHashMap<Integer, ValueObj>> foo;
Or I could make a private class "IntPair" with two properties x and y, and use that as a key... though if I do that, what's the most efficient way to do equals() and hashcode()? and will I wind up allocating too many new IntPairs? Could I keep a set of IntPairs for each x/y I've assigned, and then use a purely reflexive equals() such that I'm just checking for the exact same object instance?
Update:
Now that I've taken a closer look at Integer.valueOf(int), the specific caching model it uses wouldn't make sense here, since I'm dealing with a very sparse matrix with unpredictable entries. I really need to be caching all those IntPairs which are used, not a prespecified subset.
Intuitively, it seems to me that looking up an IntPair in a big map to see if I've already created it would, in fact, be more-or-less the same as just looking it up in the big "2-D" ConcurrentHashMap anyway, wouldn't it? So it seems the solution here is really to just use new IntPair(x,y) each time I look up a key. Yes?
It depends on how sparse your (x,y) points are, in the 40,000,000 x 40,000,000 matrix. My guess is that the matrix is going to be quite sparse anyway, so creating a lot of ConcurrentHashMaps is going to be expensive.
Your (immutable) IntPair suggestion seems more attractive in comparison. As you've suggested, you can even cache some of these pairs to improve performance (see Integer.valueOf(int) to see how this can be implemented using a static nested class and a static factory method). Since the hashcode will always be required, you can pre-compute it in the constructor and save it as a final field. To compute equals, you could use the identity equality for objects in the cache, otherwise you'll need to compare x and y individually.
EDIT: Here's the source code (OpenJDK) for Integer.valueOf(int).
ConcurrentHashMap is quite large, so you probably don't want a collection of them.
Short lived objects are actually very fast to allocate. Are you going to have to create the Integers anyway?
You could intern the coordinate objects, but the cost for just a lookup would probably be comparable to creating them anyway. The real win with Integer is that the same instances are shared when you keep around lots of them for some time.
If performance is really a huge issue, you could write (or use) a map-type object that maps longs to references. I wouldn't be surprised to see custom maps out there which also have functionality associated with coordinate systems (like finding nearest or within a range).
In response to Zach, Yes, the matrix will be very sparse.
I looked at the page you linked, and without a doubt the functionality of Integer.valueOf(int) would be ideal. If I developed a similar static method within my IntPair class, can I assume that I could define equals() to only check for strict reflexive equality?
That said, I don't see in that page where it explains how to implement that functionality using a static nested class and static factory method.... am I just missing it somehow? How do I do that?
Thanks!
I've made a Int2DMap implementation based on the standard Java HashMap. I find it is faster than using an IntPair as key. However it will need to be synchronized.
import java.io.*;
import java.util.*;
public class Int2DMap implements Map, Serializable {
private static final int DEFAULT_INITIAL_CAPACITY = 16;
private static final int MAXIMUM_CAPACITY = 1 << 30;
private static final float DEFAULT_LOAD_FACTOR = 0.75f;
protected Entry[] table;
protected int size;
protected int threshold;
protected float loadFactor;
protected transient volatile int modCount;
public Int2DMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " + loadFactor);
// Find a power of 2 >= initialCapacity
int capacity = 1;
while (capacity < initialCapacity) {
capacity <<= 1;
}
this.loadFactor = loadFactor;
this.threshold = (int) (capacity * loadFactor);
this.table = new Entry[capacity];
}
public Int2DMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public Int2DMap() {
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
}
public boolean containsKey(Object key) {
int[] xy = (int[]) key;
return containsKey(xy[0], xy[1]);
}
public Object get(Object key) {
int[] xy = (int[]) key;
return get(xy[0], xy[1]);
}
public Object put(Object key, Object value) {
int[] xy = (int[]) key;
return put(xy[0], xy[1], value);
}
public Object remove(Object key) {
int[] xy = (int[]) key;
return remove(xy[0], xy[1]);
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
protected static final int indexFor(int x, int y, int length) {
return (x * 31 + y) & (length - 1);
}
public Object get(int x, int y) {
for (Entry e = table[indexFor(x, y, table.length)]; e != null; e = e.next) {
if (e.x == x && e.y == y) {
return e.value;
}
}
return null;
}
public boolean containsKey(int x, int y) {
return getEntry(x, y) != null;
}
protected Entry getEntry(int x, int y) {
for (Entry e = table[indexFor(x, y, table.length)]; e != null; e = e.next) {
if (e.x == x && e.y == y) {
return e;
}
}
return null;
}
public Object put(int x, int y, Object value) {
int i = indexFor(x, y, table.length);
for (Entry e = table[i]; e != null; e = e.next) {
if (e.x == x && e.y == y) {
Object oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(x, y, value, i);
return null;
}
protected void resize(int newCapacity) {
Entry[] oldTable = table;
int oldCapacity = oldTable.length;
if (oldCapacity == MAXIMUM_CAPACITY) {
threshold = Integer.MAX_VALUE;
return;
}
Entry[] newTable = new Entry[newCapacity];
transfer(newTable);
table = newTable;
threshold = (int) (newCapacity * loadFactor);
}
protected void transfer(Entry[] newTable) {
Entry[] src = table;
int newCapacity = newTable.length;
for (int j = 0; j < src.length; j++) {
Entry e = src[j];
if (e != null) {
src[j] = null;
do {
Entry next = e.next;
int i = indexFor(e.x, e.y, newCapacity);
e.next = newTable[i];
newTable[i] = e;
e = next;
} while (e != null);
}
}
}
public void putAll(Map m) {
int numKeysToBeAdded = m.size();
if (numKeysToBeAdded == 0) {
return;
}
if (numKeysToBeAdded > threshold) {
int targetCapacity = (int) (numKeysToBeAdded / loadFactor + 1);
if (targetCapacity > MAXIMUM_CAPACITY)
targetCapacity = MAXIMUM_CAPACITY;
int newCapacity = table.length;
while (newCapacity < targetCapacity)
newCapacity <<= 1;
if (newCapacity > table.length)
resize(newCapacity);
}
for (Iterator i = m.entrySet().iterator(); i.hasNext();) {
Map.Entry e = (Map.Entry) i.next();
put(e.getKey(), e.getValue());
}
}
public Object remove(int x, int y) {
Entry e = removeEntryForKey(x, y);
return (e == null ? null : e.value);
}
protected Entry removeEntryForKey(int x, int y) {
int i = indexFor(x, y, table.length);
Entry prev = table[i];
Entry e = prev;
while (e != null) {
Entry next = e.next;
Object k;
if (e.x == x && e.y == y) {
modCount++;
size--;
if (prev == e)
table[i] = next;
else
prev.next = next;
e.recordRemoval(this);
return e;
}
prev = e;
e = next;
}
return e;
}
protected Entry removeMapping(Object o) {
if (!(o instanceof Entry))
return null;
Entry entry = (Entry) o;
int x = entry.x;
int y = entry.y;
int i = indexFor(x, y, table.length);
Entry prev = table[i];
Entry e = prev;
while (e != null) {
Entry next = e.next;
if (e.x == x && e.y == y) {
modCount++;
size--;
if (prev == e)
table[i] = next;
else
prev.next = next;
e.recordRemoval(this);
return e;
}
prev = e;
e = next;
}
return e;
}
public void clear() {
modCount++;
Entry[] tab = table;
for (int i = 0; i < tab.length; i++)
tab[i] = null;
size = 0;
}
public boolean containsValue(Object value) {
Entry[] tab = table;
for (int i = 0; i < tab.length; i++)
for (Entry e = tab[i]; e != null; e = e.next)
if (value.equals(e.value))
return true;
return false;
}
static class Entry implements Map.Entry {
final int x;
final int y;
Object value;
Entry next;
Entry(int x, int y, Object value, Entry next) {
this.x = x;
this.y = y;
this.value = value;
this.next = next;
}
public final Object getKey() {
return new int[] { x, y };
}
public final Object getValue() {
return value;
}
public final Object setValue(Object newValue) {
Object oldValue = value;
value = newValue;
return oldValue;
}
public final boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry e = (Map.Entry) o;
int[] xy = (int[])e.getKey();
if (x == xy[0] && y == xy[1]) {
Object v1 = getValue();
Object v2 = e.getValue();
if (v1 == v2 || (v1 != null && v1.equals(v2)))
return true;
}
return false;
}
public final int hashCode() {
return ((31 + x) * 31 + y);
}
public final String toString() {
return "[" + x + ", " + y + "]=" + value;
}
/**
* This method is invoked whenever the value in an entry is overwritten by
* an invocation of put(k,v) for a key k that's already in the HashMap.
*/
void recordAccess(Int2DMap m) {
}
/**
* This method is invoked whenever the entry is removed from the table.
*/
void recordRemoval(Int2DMap m) {
}
}
void addEntry(int x, int y, Object value, int bucketIndex) {
Entry e = table[bucketIndex];
table[bucketIndex] = new Entry(x, y, value, e);
if (size++ >= threshold)
resize(2 * table.length);
}
private abstract class HashIterator implements Iterator {
Entry next; // next entry to return
int expectedModCount; // For fast-fail
int index; // current slot
Entry current; // current entry
HashIterator() {
expectedModCount = modCount;
if (size > 0) { // advance to first entry
Entry[] t = table;
while (index < t.length && (next = t[index++]) == null)
;
}
}
public final boolean hasNext() {
return next != null;
}
final Entry nextEntry() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
Entry e = current = next;
if (e == null)
throw new NoSuchElementException();
if ((next = e.next) == null) {
Entry[] t = table;
while (index < t.length && (next = t[index++]) == null)
;
}
return e;
}
public void remove() {
if (current == null)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
int x = current.x;
int y = current.y;
current = null;
Int2DMap.this.removeEntryForKey(x, y);
expectedModCount = modCount;
}
}
private final class ValueIterator extends HashIterator {
public Object next() {
return nextEntry().value;
}
}
private final class KeyIterator extends HashIterator {
public Object next() {
return nextEntry().getKey();
}
}
private final class EntryIterator extends HashIterator {
public Map.Entry next() {
return nextEntry();
}
}
// Subclass overrides these to alter behavior of views' iterator() method
Iterator newKeyIterator() {
return new KeyIterator();
}
Iterator newValueIterator() {
return new ValueIterator();
}
Iterator newEntryIterator() {
return new EntryIterator();
}
public Set keySet() {
return new KeySet();
}
private final class KeySet extends AbstractSet {
public Iterator iterator() {
return newKeyIterator();
}
public int size() {
return size;
}
public boolean contains(Object o) {
return containsKey(o);
}
public boolean remove(Object o) {
int[] xy = (int[]) o;
return Int2DMap.this.removeEntryForKey(xy[0], xy[1]) != null;
}
public void clear() {
Int2DMap.this.clear();
}
}
public Collection values() {
return new Values();
}
private final class Values extends AbstractCollection {
public Iterator iterator() {
return newValueIterator();
}
public int size() {
return size;
}
public boolean contains(Object o) {
return containsValue(o);
}
public void clear() {
Int2DMap.this.clear();
}
}
public Set entrySet() {
return new EntrySet();
}
private final class EntrySet extends AbstractSet {
public Iterator iterator() {
return newEntryIterator();
}
public boolean contains(Object o) {
if (!(o instanceof Map.Entry))
return false;
Entry e = (Entry) o;
Entry candidate = getEntry(e.x, e.y);
return candidate != null && candidate.equals(e);
}
public boolean remove(Object o) {
return removeMapping(o) != null;
}
public int size() {
return size;
}
public void clear() {
Int2DMap.this.clear();
}
}
public static void main(String[] args) {
try {
Int2DMap map = new Int2DMap();
map.put(20, 6000, "Test");
System.out.println(map.size() == 1);
System.out.println(map.get(20, 6000) != null);
System.out.println("Test".equals(map.get(20, 6000)));
for (Iterator iter = map.values().iterator(); iter.hasNext();) {
System.out.println("Test".equals(iter.next()));
}
for (Iterator iter = map.keySet().iterator(); iter.hasNext();) {
int[] key = (int[])iter.next();
System.out.println(key[0] == 20 && key[1] == 6000);
}
for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
Map.Entry e = (Map.Entry)iter.next();
System.out.println(e.toString().equals("[20, 6000]=Test"));
}
map.remove(20, 6000);
System.out.println(map.size() == 0 && map.get(20, 6000) == null);
long start = System.nanoTime();
int max = 40000000;
for (int i = 0; i < 500000; i++) {
int x = (int)(Math.random() * max);
int y = (int)(Math.random() * max);
map.put(x, y, "");
int x2 = (int)(Math.random() * max);
int y2 = (int)(Math.random() * max);
Object o = map.get(x2, y2);
}
System.out.println(map.size());
System.out.println((System.nanoTime() - start) / 1000000);
Map map2 = new HashMap();
start = System.nanoTime();
for (int i = 0; i < 500000; i++) {
String key = "" + (int)(Math.random() * max) + "," + (int)(Math.random() * max);
map2.put(key, "");
String key2 = "" + (int)(Math.random() * max) + "," + (int)(Math.random() * max);
Object o = map2.get(key2);
}
System.out.println(map2.size());
System.out.println((System.nanoTime() - start) / 1000000);
} catch (Throwable t) {
t.printStackTrace();
}
}
}