maximize
Showing posts with label Code Example. Show all posts
Showing posts with label Code Example. Show all posts
Solr ThreadLocal DateFormat - Open Source Code Snippet
The good part of open source project is that you can read the code and learn from it. I write down the good code I learned recently here, so I refer this later.
ThreadLocal DateFormatprivate static class org.apache.solr.common.util.DateUtil.ThreadLocalDateFormat
extends ThreadLocal<DateFormat> {
DateFormat proto;
public ThreadLocalDateFormat() {
super();
SimpleDateFormat tmp = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ROOT);
tmp.setTimeZone(UTC);
proto = tmp;
}
protected DateFormat initialValue() {
return (DateFormat) proto.clone();
}
}
public static DateFormat getThreadLocalDateFormat() {
return fmtThreadLocal.get();
}
private static ThreadLocalDateFormat fmtThreadLocal = new ThreadLocalDateFormat();
Support multiple date formatsorg.apache.solr.common.util.DateUtil
static {
DEFAULT_DATE_FORMATS.add("yyyy-MM-dd'T'HH:mm:ss'Z'");
DEFAULT_DATE_FORMATS.add("yyyy-MM-dd'T'HH:mm:ss");
DEFAULT_DATE_FORMATS.add("yyyy-MM-dd");
DEFAULT_DATE_FORMATS.add("yyyy-MM-dd hh:mm:ss");
DEFAULT_DATE_FORMATS.add("yyyy-MM-dd HH:mm:ss");
DEFAULT_DATE_FORMATS.add("EEE MMM d hh:mm:ss z yyyy");
DEFAULT_DATE_FORMATS.addAll(DEFAULT_HTTP_CLIENT_PATTERNS);
}
public static Date parseDate(String d, Collection<String> fmts) throws ParseException {
if (d.endsWith("Z") && d.length() > 20) {
return getThreadLocalDateFormat().parse(d);
}
return parseDate(d, fmts, null);
}
public static Date parseDate(String dateValue, Collection dateFormats, Date startDate)
throws ParseException {
Iterator formatIter = dateFormats.iterator();
while (formatIter.hasNext()) {
String format = (String) formatIter.next();
if (dateParser == null) {
dateParser = new SimpleDateFormat(format, Locale.ROOT);
dateParser.setTimeZone(GMT);
dateParser.set2DigitYearStart(startDate);
} else {
dateParser.applyPattern(format);
}
try {
return dateParser.parse(dateValue);
} catch (ParseException pe) {
// ignore this exception, we will try the next format
}
}
}
JBoss Tips
Commands
shutdown.sh -S
run.sh -b 0.0.0.0 -c default
run.bat –Djboss.server.log.dir=d:/log
Change ports
In jboss 5, in $JBoss\server\default\conf\bindingservice.beans\META-INF\bindings-jboss-beans.xml, change the port offset of PortsDefaultBindings.
<bean name="PortsDefaultBindings" class="org.jboss.services.binding.impl.ServiceBindingSet"> <constructor> <!-- The port offset --> <parameter>1000</parameter> <!-- Set of bindings to which the "offset by X" approach can't be applied --> <parameter><null/></parameter> </constructor> </bean>
To use the port assignments defined by the Ports01Bindings bean, set the jboss.service.binding.set system property to ports-01 when starting the application server.
run -c myconfig2 -Djboss.service.binding.set=ports-01
Configuring logging
The log4j configuration file is located at server/xxx/conf/jboss-log4j.xml.
Defining a rolling log appender
<appender name="FILE"> <param name="Append" value="true"/> <param name="MaxFileSize" value="10MB"/> <param name="MaxBackupIndex" value="20"/> <param name="Threshold" value="ERROR"/> </appender>
Defining logging for your application
You can log your application by adding category entries to the jboss-log4j.xml file.
<appender name="JBIA" ...>
<param name="File" value="${jboss.server.log.dir}/jbia.log"/>
</appender>
<category name="org.jbia">
<priority value="DEBUG"/>
<appender-ref ref="JBIA" />
</category>Edit the server.xml file. For the default server in the default location, it is ${jboss.home}\server\default\deploy\jbossweb.sar\server.xml.
Uncomment the "Access logger" section. The log file will show up in server/default/log/localhost_access_log.{todays_date}.log
<Valve className="org.apache.catalina.valves.AccessLogValve"
prefix="localhost_access_log." suffix=".log"
pattern="common" directory="${jboss.server.log.dir}"
resolveHosts="false" />Configuring startup parameters
Rename run.bat for example to run-old.bat.
Create another run.bat file and put this line to it:
set JAVA_OPTS=%JAVA_OPTS% -Xms512m -Xmx1024m -XX:MaxPermSize=512m
run-old.bat -b 0.0.0.0 -c default
Dump SOAP Messages
For the case that is not easy to model as a simple DFS request, it is useful to enable the SOAP dump.
For client side, set "com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true";
For server side, set "com.sun.xml.ws.transport.http.HttpAdapter.dump=true";
In Jboass, put the following line in newly created run.bat:
set JAVA_OPTS=%JAVA_OPTS% -Dcom.sun.xml.ws.transport.http.HttpAdapter.dump=true
Enable remote debug
In newly created run.bat:
rem set JAVA_OPTS=%JAVA_OPTS% -Xrunjdwp:transport=dt_socket,address=9999,server=y,suspend=n
Configure apache httpd.conf:
LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_balancer_module modules/mod_proxy_balancer.so LoadModule proxy_ajp_module modules/mod_proxy_ajp.so <Proxy balancer://mycluster> Order deny,allow Allow from all BalancerMember http://node1.mycluster.lan:8080/ route=node1 timeout=15 BalancerMember http://node2.mycluster.lan:8080/ route=node2 timeout=15 ProxySet stickysession=JSESSIONID|jsessionid # other values: bybusyness|byrequests|bytraffic ProxySet lbmethod=bytraffic </Proxy> ProxyPass /jmx-console balancer://mycluster/jmx-console ProxyPassReverse /jmx-console http://localhost:9080/jmx-console stickysession=JSESSIONID|jsessionid
Configure JBoss
In jboss, modify {jboss.home}\server\default\deploy\jbossweb.sar\server.xml to configure the jvmRoute for sticky sessions:
<Engine name="jboss.web" defaultHost="localhost" jvmRoute="node1">
Modify {jboss.home}\server\default\deployers\jbossweb.deployer\META-INF\war-deployers-jboss-beans.xml:
<bean name="WebAppClusteringDefaultsDeploye" class="org.jboss.web.tomcat.service.deployers.ClusteringDefaultsDeployer"> <property name="useJK">true</property> </bean>
Resources:
Notes on Annotations
Notes on Annotations
Annotations
Annotations are tags that we insert into we source code so that some tool can process them. The tools can operate on the source level, or they can process class files into which the compiler has placed annotations.
Annotations provide a formalized way to add information to the code so that we can easily use that data at some later point.
Annotations are partly motivated by a general trend toward combining metadata with source-code files, instead of keeping it in external documents.
Using annotations, we can keep this metadata in the Java source code, and have the advantage of cleaner looking code, compile-time type checking and the annotation API to help build processing tools for our annotations.
To benefit from annotations, we need to select a processing tool. We insert annotations into our code that our processing tool understands, and then apply the processing tool.
Annotations can be processed at runtime, at the source code level, or at the bytecode level.
Defining annotations
Defining annotations is very easy; Annotation type declarations are similar to normal interface declarations. An at-sign (@) precedes the interface keyword. Then we declare meta-annotations on the annotation interface such as @Target to define where we can apply this annotation (a method or a field, for example), @Retention to define whether the annotations are available in the source code (SOURCE), in the class files (CLASS), or at run time (RUNTIME).
Then we declare elements in this annotation interface, elements look like interface methods, except that we can declare default values.
Methods can have default values. Method declarations must not have any parameters or a throws clause. Return types are restricted to primitives, String, Class, enums, annotations, and arrays of the preceding types.
Annotations can be read from source files, class files, or reflectively at run time.
The annotations don't do anything by themselves, without tools to read them; annotations are hardly more useful than comments.
We need write annotation processors to read and process annotations. Java SE5 provides extensions to the reflection API to read annotations defined in java class.
Annotation Syntax
An annotation without any elements is called a marker annotation.
An annotation is defined by an annotation interface, Each element declaration has the form: type elementName() default value;
Each annotation has the format
@AnnotationName(elementName1=value1, elementName2=value2, . . .)
The order of the elements does not matter.
Two special shortcuts can simplify annotations:
If no elements are specified, then we don't need to use parentheses: @BugReport
The other shortcut is the single value annotation. If an element has the special name value, and no other element is specified, then we can omit the element name and the = symbol.
@ActionListenerFor("yellowButton") is same as @ActionListenerFor(value="yellowButton")
Limitations when implement annotations
The methods of an annotation interface can have no parameters and no throws clauses, and they cannot be generic.
The type of an annotation element is one of the following: A primitive type, String, Class (with an optional type parameter such as Class), an enum type, an annotation type, 1-dimensional arrays of the preceding types (an array of arrays is not a legal element type)
The compiler will report an error if you try to use any other types. Note that you are not allowed to use any of the wrapper classes, but because of autoboxing this isn’t really a limitation. You can also have elements that are themselves annotations.
//When a Target meta-annotation is not present on an
//annotation type declaration, the declared type may be used on any
//program element.
//If no Retention annotation is present on an annotation type declaration,
//the retention policy defaults to RetentionPolicy.CLASS.
public @interface BugReport {
enum Status {
UNCONFIRMED, CONFIRMED, FIXED, NOTABUG
};
boolean showStopper() default false;
String assignedTo() default "[none]";
Class testCase() default Void.class; // we can use class
Status status() default Status.UNCONFIRMED; // we can use enum
Reference ref() default @Reference(); // an annotation type
String[] reportedBy();
// Compile error: Invalid type Object for the annotation attribute
// BugReport.object; only primitive type, String,
// Class, annotation, enumeration are permitted or 1-dimensional arrays thereof
Object object();
}
Annotation values must be compile-time constants, so you can't call method to set annotation values.
// Compile error: The value for annotation attribute ActionListenerFor.source must be a constant expression
@ActionListenerFor(source = "blueButton" + anyMethod())
An annotation element can never be set to null. Not even a default of null is permissible.
Annotations don’t support inheritance, you cannot use the “extends” keyword with @interfaces.
If annotations (retention class) are evaluated by the compiler, all element values must be compile-time constants.
An item can have multiple annotations, provided they belong to different types. We cannot use the same annotation type more than once when annotating a particular item.
If this is a problem, we can design an annotation that has a value of an array of simpler annotations.
Default value constraints
The compiler is quite picky about default element values. No element can have an unspecified value. This means that elements must either have default values or values provided by the class that uses the annotation.
There is another restriction, which is that none of the non-primitive type elements are allowed to take null as a value, either when declared in the source code or when defined as a default value in the annotation interface. You need define special value as default value.
It is legal to apply an annotation to itself. For example, the @Documented annotation is itself annotated as @Documented.
Annotations for local variables can only be processed at the source level. Class files do not describe local variables. Therefore, all local variable annotations are discarded when a class is compiled. Similarly, annotations for packages are not retained beyond the source level.
Implementation detail
All annotation interfaces implicitly extend the interface java.lang.annotation.Annotation. That interface is a regular interface, not an annotation interface.
Standard Annotations
Meta-Annotations
@Target
The @Target meta-annotation restricts the items to which the annotation applies.
@Target(ElementType.ANNOTATION_TYPE)
public enum ElementType
{TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE,,ANNOTATION_TYPE,PACKAGE}
An annotation without an @Target restriction can be applied to any program element. The compiler checks that we apply an annotation only to a permitted item.
@Retention
The @Retention meta-annotation specifies how long an annotation is retained. We specify at most one of the values.
@Retention(RetentionPolicy.RUNTIME)
SOURCE Annotations are not included in class files.
CLASS Annotations are included in class files, but the virtual machine need not load them.
RUNTIME Annotations are included in class files and loaded by the virtual machine. They are available through the reflection API.
public enum RetentionPolicy {
* Annotations are to be discarded by the compiler.
SOURCE,
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default behavior.
CLASS,
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
RUNTIME
}
If no Retention annotation is present on an annotation type declaration, the retention policy defaults to RetentionPolicy.CLASS.
The @Documented meta-annotation gives a hint to documentation tools such as Javadoc.
@Inherited
The @Inherited meta-annotation applies only to annotations for classes. When a class has an inherited annotation, then all of its subclasses automatically have the same annotation.
Annotations for Compilation
@Deprecated
The @SuppressWarnings annotation tells the compiler to suppress warnings of a particular type: @SuppressWarnings("unchecked")
The @Override annotation applies only to methods. The compiler checks that a method with this annotation really overrides a method from the superclass.
The @Generated annotation is intended for use by code generator tools. Any generated source code can be annotated to differentiate it from programmer-provided code.
Annotations for Managing Resources
@PostConstruct, @PreDestroy, @Resource
Practical usage
Source-Level Annotation Processing
One use for annotation is the automatic generation of "side files" that contain additional information about programs
Bytecode Engineering
We can process class files using Bytecode Engineering Library (BCEL).
Generating external files
How Junit process annotation.
Resources:
Labels:
Code Example,
Interview,
J2SE,
Java,
Soft Skills
Learning JDK Code - Collection
Learning JDK Code - Collection
HashMap vs Hashtable
The Hashtable is among the original collection classes in Java.Hashtable extends the Dictionary class, which as the Javadocs state, is obsolete and has been replaced by the Map interface. HashMap is part of the new Collections Framework, added with Java 2.
The key difference between the two is that access to the Hashtable is synchronized on the table while access to the HashMap is not synchronized.This makes HashMap better for non-threaded applications, as unsynchronized Objects typically perform better than synchronized ones
HashMap has a more complex hashing algorithm then Hashtable. It takes the hash value from the key and then hashes it again (double hashing). This can improve the distribution of the keys and hence the performance of the Map.
Another difference is that iterator in the HashMap is fail-safe while the enumerator for the Hashtable isn't. If we change the map while iterating, it will throw exception.
Third difference is that HashMap permits null values in it, while Hashtable doesn't. Also note that only one NULL value is allowed as a key in HashMap. HashMap does not allow multiple keys to be NULL. Nevertheless, it can have multiple NULL values.
1. Initial size and resize
HashMap uses power-of-two length tables, default capacity is 16.
static final int DEFAULT_INITIAL_CAPACITY = 16;
static final int MAXIMUM_CAPACITY = 1 << 30;
static final float DEFAULT_LOAD_FACTOR = 0.75f;
public HashMap(int initialCapacity, float loadFactor) {
// Find a power of 2 >= initialCapacity
int capacity = 1;
while (capacity < initialCapacity)
capacity <<= 1;
}
User can specify map size, hashmap would find a pow of 2 whose value is just larger than user specified size.
resize(2 * table.length);
Hashset would construct a new, empty hashtable with the specified initial capacity.
Default size is 11.
public Hashtable(int initialCapacity, float loadFactor) {
if (initialCapacity==0)
initialCapacity = 1;
this.loadFactor = loadFactor;
table = new Entry[initialCapacity];
threshold = (int)(initialCapacity * loadFactor);
}
public Hashtable() {
this(11, 0.75f);
}
int newCapacity = oldCapacity * 2 + 1;
HashMap hash function
The way the HashMap is implemented relies on the hashCode function being sufficiently well implemented. If you have many collisions on the lower bits, the HashMap will not perform well.
Because the implementation of hashCode is outside of the control of HashMap (every object can implement their own), they supply an additional hash function that shifts the object's hashCode around a little to ensure that the lower bits are distributed more randomly.
HashMap uses power-of-two length tables, and hashes keys by masking away the higher bits and taking only the lower bits of their hash code.
So hash() attempts to bring relevancy to the higher bits, which otherwise would get masked away (indexFor basically discards the higher bits of h and takes only the lower k bits where length == (1 << k)).
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
* Applies a supplemental hash function to a given hashCode, which
* defends against poor quality hash functions. This is critical
* because HashMap uses power-of-two length hash tables, that
* otherwise encounter collisions for hashCodes that do not differ
* in lower bits. Note: Null keys always map to hash 0, thus index 0.
static int hash(int h) {
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
static int indexFor(int h, int length) {
return h & (length-1);
}
Hashtable hash function
By doing the more expensive % operation (instead of simple bit masking), the performance of Hashtable is less sensitive to hash codes with poor distribution in the lower bits (especially if table.length is a prime number).
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
HashMap[Sun JDK]
public class HashMap extends AbstractMap implements Map, Cloneable, Serializable
{
// The next size value at which to resize (capacity * load factor).
int threshold;
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR;
threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR); //
table = new Entry[DEFAULT_INITIAL_CAPACITY];
init(); // subclass would overwite this
}
public V put(K key, V value) {
if (key == null)
return putForNullKey(value); // We can put null key and null value to HashMap.
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) // call e.key == key
{
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}
void addEntry(int hash, K key, V value, int bucketIndex) {
Entry e = table[bucketIndex];
table[bucketIndex] = new Entry(hash, key, value, e);
if (size++ >= threshold)
resize(2 * table.length);
}
public boolean containsKey(Object key) {
return getEntry(key) != null;
}
final Entry<K,V> getEntry(Object key) {
int hash = (key == null) ? 0 : hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
}
/**
* Applies a supplemental hash function to a given hashCode, which
* defends against poor quality hash functions. This is critical
* because HashMap uses power-of-two length hash tables, that
* otherwise encounter collisions for hashCodes that do not differ
* in lower bits. Note: Null keys always map to hash 0, thus index 0.
*/
static int hash(int h) {
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
static int indexFor(int h, int length) {
return h & (length-1);
}
public boolean containsValue(Object value) {
if (value == null)
return containsNullValue();
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<K,V> implements Map.Entry<K,V> {
final K key;
V value;
Entry<K,V> next;
final int hash;
public final boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry e = (Map.Entry)o;
Object k1 = getKey();
Object k2 = e.getKey();
if (k1 == k2 || (k1 != null && k1.equals(k2))) {
Object v1 = getValue();
Object v2 = e.getValue();
if (v1 == v2 || (v1 != null && v1.equals(v2)))
return true;
}
return false;
}
public final int hashCode() {
return (key==null ? 0 : key.hashCode()) ^
(value==null ? 0 : value.hashCode());
}
}
private abstract class HashIterator<E> implements Iterator<E> {
Entry<K,V> next; // next entry to return
int expectedModCount; // For fast-fail
int index; // current slot
Entry<K,V> 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<K,V> nextEntry() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
Entry<K,V> e = next;
if (e == null)
throw new NoSuchElementException();
if ((next = e.next) == null) {
Entry[] t = table;
while (index < t.length && (next = t[index++]) == null)
;
}
current = e;
return e;
}
public void remove() {
if (current == null)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
Object k = current.key;
current = null;
HashMap.this.removeEntryForKey(k);
expectedModCount = modCount;
}
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);
}
void transfer(Entry[] newTable) {
Entry[] src = table;
int newCapacity = newTable.length;
for (int j = 0; j < src.length; j++) {
Entry<K,V> e = src[j];
if (e != null) {
src[j] = null;
do {
Entry<K,V> next = e.next;
int i = indexFor(e.hash, newCapacity);
e.next = newTable[i];
newTable[i] = e;
e = next;
} while (e != null);
}
}
}
private final class ValueIterator extends HashIterator<V> {
public V next() {
return nextEntry().value;
}
}
private final class KeyIterator extends HashIterator<K> {
public K next() {
return nextEntry().getKey();
}
}
private final class EntryIterator extends HashIterator<Map.Entry<K,V>> {
public Map.Entry<K,V> next() {
return nextEntry();
}
}
// Subclass overrides these to alter behavior of views' iterator() method
Iterator<K> newKeyIterator() {
return new KeyIterator();
}
Iterator<V> newValueIterator() {
return new ValueIterator();
}
Iterator<Map.Entry<K,V>> newEntryIterator() {
return new EntryIterator();
}
// Views
private transient Set<Map.Entry<K,V>> entrySet = null;
}
public Set<K> keySet() {
Set<K> ks = keySet;
return (ks != null ? ks : (keySet = new KeySet()));
}
private final class KeySet extends AbstractSet<K> {
public Iterator<K> iterator() {
return newKeyIterator();
}
public int size() {
return size;
}
public boolean contains(Object o) {
return containsKey(o);
}
public boolean remove(Object o) {
return HashMap.this.removeEntryForKey(o) != null;
}
public void clear() {
HashMap.this.clear();
}
}
public Collection<V> values() {
Collection<V> vs = values;
return (vs != null ? vs : (values = new Values()));
}
private final class Values extends AbstractCollection<V> {
public Iterator<V> iterator() {
return newValueIterator();
}
public int size() {
return size;
}
public boolean contains(Object o) {
return containsValue(o);
}
public void clear() {
HashMap.this.clear();
}
}
private void writeObject(java.io.ObjectOutputStream s)
throws IOException
{
Iterator<Map.Entry<K,V>> i =
(size > 0) ? entrySet0().iterator() : null;
// Write out the threshold, loadfactor, and any hidden stuff
s.defaultWriteObject();
// Write out number of buckets
s.writeInt(table.length);
// Write out size (number of Mappings)
s.writeInt(size);
// Write out keys and values (alternating)
if (i != null) {
while (i.hasNext()) {
Map.Entry<K,V> e = i.next();
s.writeObject(e.getKey());
s.writeObject(e.getValue());
}
}
}
private void readObject(java.io.ObjectInputStream s)
throws IOException, ClassNotFoundException
{
// Read in the threshold, loadfactor, and any hidden stuff
s.defaultReadObject();
// Read in number of buckets and allocate the bucket array;
int numBuckets = s.readInt();
table = new Entry[numBuckets];
init(); // Give subclass a chance to do its thing.
// Read in size (number of Mappings)
int size = s.readInt();
// Read the keys and values, and put the mappings in the HashMap
for (int i=0; i<size; i++) {
K key = (K) s.readObject();
V value = (V) s.readObject();
putForCreate(key, value);
}
}
}
Hashtable
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable {
private transient Entry[] table;
private transient int count;
private int threshold;
private float loadFactor;
public Hashtable(int initialCapacity, float loadFactor) {
this.loadFactor = loadFactor;
table = new Entry[initialCapacity];
threshold = (int)(initialCapacity * loadFactor);
}
public Hashtable(Map<? extends K, ? extends V> t) {
this(Math.max(2*t.size(), 11), 0.75f);
putAll(t);
}
public synchronized V get(Object key) {
Entry tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
return e.value;
}
}
return null;
}
public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException();
}
// Makes sure the key is not already in the hashtable.
Entry tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
V old = e.value;
e.value = value;
return old;
}
}
modCount++;
if (count >= threshold) {
// Rehash the table if the threshold is exceeded
rehash();
tab = table;
index = (hash & 0x7FFFFFFF) % tab.length;
}
// Creates the new entry.
Entry<K,V> e = tab[index];
tab[index] = new Entry<K,V>(hash, key, value, e);
count++;
return null;
}
protected void rehash() {
int oldCapacity = table.length;
Entry[] oldMap = table;
int newCapacity = oldCapacity * 2 + 1;
Entry[] newMap = new Entry[newCapacity];
modCount++;
threshold = (int)(newCapacity * loadFactor);
table = newMap;
for (int i = oldCapacity ; i-- > 0 ;) {
for (Entry<K,V> old = oldMap[i] ; old != null ; ) {
Entry<K,V> e = old;
old = old.next;
int index = (e.hash & 0x7FFFFFFF) % newCapacity;
e.next = newMap[index];
newMap[index] = e;
}
}
}
public synchronized V remove(Object key) {
Entry tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry<K,V> e = tab[index], prev = null ; e != null ; prev = e, e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
modCount++;
if (prev != null) {
prev.next = e.next;
} else {
tab[index] = e.next;
}
count--;
V oldValue = e.value;
e.value = null;
return oldValue;
}
}
return null;
}
public synchronized void putAll(Map<? extends K, ? extends V> t) {
for (Map.Entry<? extends K, ? extends V> e : t.entrySet())
put(e.getKey(), e.getValue());
}
public synchronized void clear() {
Entry tab[] = table;
modCount++;
for (int index = tab.length; --index >= 0; )
tab[index] = null;
count = 0;
}
public synchronized boolean containsKey(Object key) {
Entry tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
return true;
}
}
return false;
}
}
public abstract class AbstractMap<K,V> implements Map<K,V> {
public int hashCode() {
int h = 0;
Iterator<Entry<K,V>> i = entrySet().iterator();
while (i.hasNext())
h += i.next().hashCode();
return h;
}
*/
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Map))
return false;
Map<K,V> m = (Map<K,V>) o;
if (m.size() != size())
return false;
try {
Iterator<Entry<K,V>> i = entrySet().iterator();
while (i.hasNext()) {
Entry<K,V> e = i.next();
K key = e.getKey();
V value = e.getValue();
if (value == null) {
if (!(m.get(key)==null && m.containsKey(key)))
return false;
} else {
if (!value.equals(m.get(key)))
return false;
}
}
} catch (ClassCastException unused) {
return false;
} catch (NullPointerException unused) {
return false;
}
return true;
}
}
LinkedHashMap[TODO]
public class LinkedHashMap extends HashMap implements Map
{
// The head of the doubly linked list.
private transient Entry header;
* The iteration ordering method for this linked hash map: true
* for access-order, false for insertion-order.
private final boolean accessOrder;
void init() {
header = new Entry(-1, null, null, null);
header.before = header.after = header;
}
}
HashSet
public class HashSet extends AbstractSet implements Set, Cloneable, java.io.Serializable
{
private transient HashMap map;
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
public HashSet() {map = new HashMap();}
public boolean add(E e) {return map.put(e, PRESENT)==null;}
}
TreeMap
public class TreeMap extends AbstractMap
implements NavigableMap, Cloneable, java.io.Serializable
// it does not extend HashMap
{
private final Comparator comparator;
private transient Entry root = null;
private transient int modCount = 0;
// private Entry getEntry(Object key)
* Returns a Set view of the keys contained in this map. The set's
* iterator will return the keys in ascending order. The map is backed by
* this TreeMap instance, so changes to this map are reflected in
* the Set, and vice-versa. The Set supports element removal, which
* removes the corresponding mapping from the map, via the
* Iterator.remove, Set.remove, removeAll,
* retainAll, and clear operations. It does not support
* the add or addAll operations.
* @return a set view of the keys contained in this TreeMap.
public Set keySet() {
if (keySet == null) {
keySet = new AbstractSet() {
public Iterator iterator() {
return new KeyIterator();
}
public int size() {
return TreeMap.this.size();
}
public boolean contains(Object o) {
return containsKey(o);
}
public boolean remove(Object o) {
int oldSize = size;
TreeMap.this.remove(o);
return size != oldSize;
}
public void clear() {
TreeMap.this.clear();
}
};
}
return keySet;
}
public Collection values() {
if (values == null) {
values = new AbstractCollection() {
public Iterator iterator() {
return new ValueIterator();
}
public int size() {
return TreeMap.this.size();
}
public boolean contains(Object o) {
for (Entry e = firstEntry(); e != null; e = successor(e))
if (valEquals(e.getValue(), o))
return true;
return false;
}
public boolean remove(Object o) {
for (Entry e = firstEntry(); e != null; e = successor(e)) {
if (valEquals(e.getValue(), o)) {
deleteEntry(e);
return true;
}
}
return false;
}
public void clear() {
TreeMap.this.clear();
}
};
}
return values;
}
public boolean containsValue(Object value) {
return (root==null ? false :
(value==null ? valueSearchNull(root)
: valueSearchNonNull(root, value)));
}
private boolean valueSearchNull(Entry n) {
if (n.value == null)
return true;
// Check left and right subtrees for value
return (n.left != null && valueSearchNull(n.left)) ||
(n.right != null && valueSearchNull(n.right));
}
private boolean valueSearchNonNull(Entry n, Object value) {
// Check this node for the value
if (value.equals(n.value))
return true;
// Check left and right subtrees for value
return (n.left != null && valueSearchNonNull(n.left, value)) ||
(n.right != null && valueSearchNonNull(n.right, value));
}
static final class Entry implements Map.Entry {
K key;
V value;
Entry left = null;
Entry right = null;
Entry parent;
boolean color = BLACK;
}
// Returns the first Entry in the TreeMap (according to the TreeMap's
// key-sort function). Returns null if the TreeMap is empty.
final Entry getFirstEntry() {
Entry p = root;
if (p != null)
while (p.left != null)
p = p.left;
return p;
}
public boolean containsValue(Object value) {
for (Entry e = getFirstEntry(); e != null; e = successor(e))
if (valEquals(value, e.value))
return true;
return false;
}
//final Entry getLastEntry()
// Returns the successor of the specified Entry, or null if no such.
static TreeMap.Entry successor(Entry t) {
if (t == null)
return null;
else if (t.right != null) {
Entry p = t.right;
while (p.left != null)
p = p.left;
return p;
} else {
Entry p = t.parent;
Entry ch = t;
while (p != null && ch == p.right) {
ch = p;
p = p.parent;
}
return p;
}
}
// Returns the predecessor of the specified Entry, or null if no such.
static Entry predecessor(Entry t) {
if (t == null)
return null;
else if (t.left != null) {
Entry p = t.left;
while (p.right != null)
p = p.right;
return p;
} else {
Entry p = t.parent;
Entry ch = t;
while (p != null && ch == p.left) {
ch = p;
p = p.parent;
}
return p;
}
}
}
[TODO]
How BlockingQueue and ConcurrentHashMap are implemented?
ThreadLocal
public class ThreadLocal {
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null)
return (T)e.value;
}
return setInitialValue();
}
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
}
Labels:
Code Example,
J2SE,
Java,
Learning code,
Soft Skills
Subscribe to:
Posts (Atom)
Labels
ANT
(6)
Algorithm
(69)
Algorithm Series
(35)
Android
(7)
Big Data
(7)
Blogger
(14)
Bugs
(6)
Cache
(5)
Chrome
(19)
Code Example
(29)
Code Quality
(7)
Coding Skills
(5)
Database
(7)
Debug
(16)
Design
(5)
Dev Tips
(63)
Eclipse
(32)
Git
(5)
Google
(33)
Guava
(7)
How to
(9)
Http Client
(8)
IDE
(7)
Interview
(88)
J2EE
(13)
J2SE
(49)
JSON
(7)
Java
(186)
JavaScript
(27)
Learning code
(9)
Lesson Learned
(6)
Linux
(26)
Lucene-Solr
(112)
Mac
(10)
Maven
(8)
Network
(9)
Nutch2
(18)
Performance
(9)
PowerShell
(11)
Problem Solving
(11)
Programmer Skills
(6)
Scala
(6)
Security
(9)
Soft Skills
(38)
Spring
(22)
System Design
(11)
Testing
(7)
Text Mining
(14)
Tips
(17)
Tools
(24)
Troubleshooting
(29)
UIMA
(9)
Web Development
(19)
Windows
(21)
adsense
(5)
bat
(8)
regex
(5)
xml
(5)