Beruflich Dokumente
Kultur Dokumente
Location: http://www.jguru.com/faq/Collections
Ownership: http://www.jguru.com/misc/user-agree.jsp#ownership.
Rumor has it that the Dictionary class is so old that the concept of interfaces didn't
exist yet. Once interfaces were introduced, nobody bothered to change Dictionary to
an interface.
The Generic Collection Library for Java - JGL from ObjectSpace has been around
since 1996 and the same version works with both JDK 1.1 and the Java 2 SDK. Doug
Lea's Collections Package is a precursor to the current Collections Framework. If you
are looking for template support, the Generic Java Language Extension includes a
retrofitted version of the Collections Framework with template support. A new entry
into the mix is Colt which is meant for scientific computing, and includes data
structures for numerical operations.
Comments and alternative answers
Where can I find an article comparing JGL and the Collections Framework?
Location: http://www.jguru.com/faq/view.jsp?EID=966
Created: Nov 14, 1999
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7)
JavaWorld posted an article comparing the two frameworks back in their January
1999 issue: The battle of the container frameworks: which should you use?
Where do I get the Collections Framework for use with JDK 1.1?
Location: http://www.jguru.com/faq/view.jsp?EID=969
Created: Nov 14, 1999
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7)
The subset of the Collections Framework for use with JDK 1.1 is available with the
InfoBus information:
http://java.sun.com/beans/infobus/index.html#DOWNLOAD_COLLECTIONS.
According to the exam objectives, you need to: "Make appropriate selection of
collection classes/interfaces to suit specified behavior requirements."
Comments and alternative answers
Helpfull....
Author: Ola Tartakovsky (http://www.jguru.com/guru/viewbio.jsp?EID=863596),
May 2, 2002
-
The Map interface can be used to count the number of times a word/object appears.
The following program demonstrates counting word frequency from the command
line:
import java.util.*;
This is actually outside the scope of the Collections Framework. Instead, it is part of
the java.text package with the Collator and CollationKey classes.
import java.text.*;
import java.util.*;
import java.util.*;
class Sort {
list.addElement(new String("parag"));
list.addElement(new String("amit"));
list.addElement(new String("priyank"));
Collections.sort(list);
System.out.println(list);
s.sort();
s.print();
class Sort {
public Sort() {
list.addElement(new String("parag"));
list.addElement(new String("amit"));
list.addElement(new String("priyank"));
Collections.sort(list);
System.out.println(list);
s.sort();
s.print();
}
You need to use a new Comparator, not the default Comparable. The String class
comes with a special Comparator you can use: String.CASE_INSENSITIVE_ORDER.
A red-black tree is a binary search tree where every node has two children or is a
leaf. It ensures O(log N) search times, at a cost of a more complicated insertion (and
deletion) process. In a red-black tree, every node is colored either red or black, with
a black root node, though a black root node isn't a requirement. In addition, if a
node is red, its children must be black and every path from root to leaf (or null child
node) must contain the same number of black nodes. These rather obscure rules
ensure the tree is balanced.
You cannot directly make an array larger. You must make a new (larger) array and
copy the original elements into it, usually with System.arraycopy(). If you find
yourself frequently doing this, the Vector class does this automatically for you, as
long as your arrays are not of primitive data types.
How do you store a primitive data type within a Vector or other collections
class?
Location: http://www.jguru.com/faq/view.jsp?EID=983
Created: Nov 14, 1999
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7)
You need to wrap the primitive data type into one of the wrapper classes found in the
java.lang package, like Integer, Float, or Double, as in:
No pointers does not mean no reference variables. You just can't deference them as
you can in C/C++ or perform pointer arithmetic. You can still use abstract data types
that require dynamic data structures. See the LinkedList class for an example of a
linked list implementation.
The Collections Framework is a core part of the Java 2 platform. You don't have to
download anything more than the Java 2 SDK. For more information about the
framework, the main documentation is available at
http://www.javasoft.com/products/jdk/1.2/docs/guide/collections/.
There also is a subset of the Collections Framework available for JDK 1.1, see
http://java.sun.com/beans/infobus/#collections.
Where can I find information about the design decisions made during the
development of the Collections Framework?
Location: http://www.jguru.com/faq/view.jsp?EID=1179
Created: Nov 20, 1999
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7)
Which is the preferred collection class to use for storing database result
sets?
Location: http://www.jguru.com/faq/view.jsp?EID=2286
Created: Dec 9, 1999 Modified: 2000-07-30 09:48:38.772
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7)
When retrieving database results, the best collection implementation to use is the
LinkedList. The benefits include:
Basically:
ResultSet result = stmt.executeQuery("...");
List list = new LinkedList();
while(result.next()) {
list.add(result.getString("col"));
}
If there are multiple columns in the result set, you'll have to combine them into their
own data structure for each row. Arrays work well for that as you know the size,
though a custom class might be best so you can convert the contents to the proper
type when extracting from databse, instead of later.
If the Iterator interface extended the Enumeration interface, the Iterator interface
would end up with five methods where two methods just called other methods in the
interface. The designers of the framework wanted to get rid of the cumbersome
Enumeration method names so had the Iterator interface stand on its own with new
shorter method names.
With the Collections Framework, the new implementations are all unsynchronized by
default. If you need synchronized access, you must synchronize things yourself. The
Collections class offers a wrapper method for each of the six core collection
interfaces that add synchronization to an arbitrary collections implementation. To
ensure thread-safety, direct access to the original backing collection must be
avoided.
For example, the following will synchronize an arbitrary List and lose the original
reference so you can't access it directly:
How can I speed up array accesses and turn off array bounds checking?
Location: http://www.jguru.com/faq/view.jsp?EID=3038
Created: Dec 20, 1999
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7)
You cannot. It is part of the security architecture of the Java runtime to ensure never
accessing invalid memory space.
Comments and alternative answers
The null-pointer check can also be moved out of the loop via "loop-invariant code
motion" stuff.
Does any of this really happen? Haven't checked, but I hope so. ;) In principle,
dynamic compilers can do much more of this than a JIT or other a priori compiler.
I'm not sure if it still applies in the current family of jre's, but apparently you used
to be able to turn off the Array Bound checking by encapsulating your array
access in a try/catch;
try {
myArray[i] = i;
//to be expected
}
Even if this did work, I expect it would only be faster for very large arrays,
richard
See http://c2.com/cgi/wiki?CatchDontCheck
Greetings
Bernd
How do I get the list of system properties that tell me things like which
version of Java a user is running and their platform-specific line separator?
Location: http://www.jguru.com/faq/view.jsp?EID=3825
Created: Dec 31, 1999 Modified: 2000-02-21 09:27:19.682
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7)
The System.getProperties() method will return the standard property set. However,
in untrusted applets, you can only ask for specific properties, as in
System.getProperty("java.version").
Arrays.sort(theArray);
If, however, it is an array of objects that don't implement the Comparable interface
then you need to provide a custom Comparator to help you sort the elements in the
array.
Arrays.sort(theArray, theComparator);
How can I implement a List (ordered collection) that keeps an index (i.e. a
Map) of its contents?
Location: http://www.jguru.com/faq/view.jsp?EID=11808
Created: Feb 6, 2000 Modified: 2001-07-24 09:21:44.644
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7)
You can't. Each of the Map and List interfaces define a remove(Object o) method.
Each method returns a different type (Map returns an Object while List returns a
boolean). Because the compiler doesn't permit overloaded methods that differ by
only return type, you cannot create a class that implements both the List and Map
interface.
If you need a Map that maintains insertion order, see the LinkedHashMap added in
Java 1.4.
Both of my Lists also have a toMap() method which returns a true java.util.Map
object for you to play with.
How can I save/load application settings that I would normally use .ini files
or the Windows Registry?
Location: http://www.jguru.com/faq/view.jsp?EID=20462
Created: Mar 5, 2000 Modified: 2005-09-12 14:42:49.101
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7) Question
originally posed by chih-ming yan
(http://www.jguru.com/guru/viewbio.jsp?EID=20234
You can use Java property files for storing settings for an application. Use the
java.util.Properties class, which includes a load and store method.
What collection works best for maintaining a family tree, where each node
can have multiple parents and multiple children, spouse relationships, etc.?
Location: http://www.jguru.com/faq/view.jsp?EID=26298
Created: Mar 20, 2000 Modified: 2000-03-20 17:42:30.647
Author: Joseph Shelby (http://www.jguru.com/guru/viewbio.jsp?EID=26292)
Question originally posed by John Zukowski PREMIUM
(http://www.jguru.com/guru/viewbio.jsp?EID=7
With Collections by themselves, there isn't one. What you're asking for is a Labeled
Directed Graph (A directed graph where the graph edges have labels describing the
relationship). A rather complex object.
You'd have to design that yourself (though you can use Collection objects like Lists in
the implementation as a convenience), and design Comparators to support your final
implementation classes of a "FamilyTreePerson" for sorting purposes (like sort by
name or sort by birthdate, etc.).
After that, you have to decide what "Iteration" over the tree really means and define
Iterator classes over the Graph. After that, completing the Collection interface should
be pretty simple.
In other words, you've got a lot of design work to do, but designing it well can lead
to a rather flexible framework (or at least a source of Patterns) for future use. In
particular, keep in mind in building such a LabeledDirectedGraph beast on how you
can keep "Family Tree" concepts out of it. The Label provider should be an Interface
function object, like Comparator.
This is getting heavily into "Generic Programming", and I advise you read more
about that (most GP work is being done in connection with the STL from C++).
This works similarly to the way the (hidden) Synchronized versions in Collections
work. They contain a reference to the original collection object that does the "real"
work, but restrict access to it by synchronizing all the access methods.
What you'd be doing in this case is restricting access by keeping a reference to the
Class object of the class you want to restrict your collection to contain, and throw
IllegalArgumentExceptions whenever there's an attempt to add an object not of that
class.
There's no way to enforce compile-time type safety in this manner. The API using
"Object" references can't be changed in Collection.
You can also wrap a collection by a Proxy that provides the alternative API that has
type-safe method signatures. This is what's done by the StringTokenizer API (which
implements Enumeration, and wraps Enumeration with String versions of the same
methods).
Otherwise, create your own class with its own signatures, and keep the Collection
strictly private. This is best done if you are designing a class for others to use.
If speed is of the essence, do not use a Vector. Instead, use an ArrayList. All
accesses to a Vector are synchronized, whether you need it or not. If you know you
aren’t accessing the structure from multiple threads, the ArrayList will be much
faster.
With that said, what about if you need to stay with a Vector? There are at least four
ways to traverse through all the elements of a Vector:
Of the four, there are neglible differences in performance. While looping through to a
specific index is a little faster, you lose the flexibility of changing to another data
structure at a later time. With the Enumeration / Iterator approach, there is the
added cost to create the Enumeration/Iterator to walk through. With the exception
approach, you are relying on NoSuchElementException to be thrown to catch the
ending of the walk through. While creating the exception takes time, this approach
avoids the repeated test of hasMoreElement(). As the structure gets larger, avoiding
the test condition can save lots of time.
Added by Doug Bell:
You left out what is often the fastest means to sequence though the members of a
Vector: get a copy of the elements in an array and sequence through the array. This
results in either synchronized calls, after which there is not any method overhead at
all:
Object[] elements = vector.toArray(); // JDK 1.2
or
Object[] elements;
synchronized (vector) { // needed if
concurrently accessed
elements = new Object[vector.size()];
vector.copyInto(elements);
}
Further, if you know the types of the elements in the Vector, you can put the copy of
the elements in an array of the known type and eliminate the casting overhead
necessary to cast the Object references to the known type.
JDK 1.1:
MyType[] elements;
synchronized (vector) { // needed if
concurrently accessed
elements = new MyType[vector.size()];
vector.copyInto(elements);
}
JDK 1.2:
MyType[] elements = new MyType[vector.size()];
elements = (MyType[])vector.toArray(elements);
Note that while System.arraycopy() still needs to check the types of the objects
when copying between arrays of different types, the check is performed much more
efficiently than performing the cast operation on each element individually.
Getting an array of elements is faster than the other suggested approaches for
vectors of more than a few elements. Although it does incur the overhead of
instantiating a copy of the array and copying the elements, these operations
generally take much less time than the repeated synchronization. As an added
benefit (usually at least, depends on what you're trying to do) the process of
iterating through the elements is predictable even in the presence of other threads
which modify the vector. (You can also achieve this using any of the other techniques
by placing the code that sequences the vector in a block synchronized on the
Vector object.)
A fifth way actually exists that is faster for traversal, but requires additional setup
and memory. Copy the elements out of the collection and into an array. You can even
make the array the right data type.
The Hashtable class uses an internal (private) class named Entry to hold the key-
value pairs. All entries of the Hashtable are stored in an array of Entry objects with
the hash value of the key serving as the index. If two or more different keys have
the same hash value these entries are stored as a linked list under the same index.
To go through all the elements of a HashMap, or any class that implements the Map
interface, call the entrySet() or keySet() methods than loop through what is
returned. The entrySet() returns a group of Map.Entry elements, whereas the
keySet() method just returns a Set of key elements. If you then want what the key
refers to, you'd have to look them up.
Once you have a Set to work with, you would then use an Iterator to go through all
its elements. The following demonstrates:
• unmodifiableCollection(Collection c)
• unmodifiableList(List list)
• unmodifiableMap(Map m)
• unmodifiableSet(Set s)
• unmodifiableSortedMap(SortedMap m)
• unmodifiableSortedSet(SortedSet s)
If you then get an Iterator from one of these unmodifiable collections, when you call
remove() it will throw an UnsupportedOperationException.
In order to get all the keys for a Hashtable, you use the keys() method to get an
Enumeration or the keySet() method to get a Set. If you are using Java 2, and can
use the collections framework, what you should do is get the key set of the
Hashtable and create a TreeSet from it. You can then get an iterator() from the
created TreeSet that will have the keys in order. If you can't use the collections
framework, you'll have the sort the Enumeration you get back from keys() yourself.
Comments and alternative answers
while (it.hasNext()) {
So, not only does it answer the question, it does so in a very terse and elegant
manner.
while (it.hasNext()) {
// corresponding value...
So, not only does it answer the question, it does so in a very terse and elegant
manner.
while (it.hasNext()) {
// corresponding value...
So, not only does it answer the question, it does so in a very terse and elegant
manner.
The original collection classes in Java are all synchronized: Vector and Hashtable,
along with their subclasses Stack and Properties. Those classes introduced with the
Java 2 Collections Framework are all NOT synchronized by default, the sets, lists, and
maps. If you need to synchronize those, see How do I synchronize a collection?.
With a LinkedList, the List implementation is backed by a doubly linked list data
structure, allowing easy inserts/deletions anywhere in the structure, but really slow
random accesses as the access must start at an end to get to the specific position.
Which you use really depends on the type of operations you need to support.
Colt offers, among others, efficient and usable data structures and algorithms for
Off-line and On-line Data Analysis, Linear Algebra, Multi-dimensional arrays,
Statistics, Histogramming, Monte Carlo Simulation, Parallel & Concurrent
Programming.
There is no requirement that the elements are returned in the same order, only that
all of them are returned in the Enumeration. Your best bet for getting the element for
a key is to loop through the keys() returned and fetch the element for each. Or, if
you can use a HashMap instead of a Hashtable, work with the Map.Entry that is
returned by the keySet(). This includes both the key and value together, not
requiring a separate lookup.
How do I treat an object I get out of a Vector (collection) as the type I put
into it?
Location: http://www.jguru.com/faq/view.jsp?EID=207192
Created: Sep 15, 2000 Modified: 2000-09-15 14:09:12.012
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7) Question
originally posed by Li Changen
(http://www.jguru.com/guru/viewbio.jsp?EID=124609
When you get an object out of a Vector (or any collection), the object is returned as
being of type Object. You need to cast it back into the object type you put into the
data structure if you need to call or treat the object as the original type.
What is the difference between a singly linked list and doubley linked list?
Location: http://www.jguru.com/faq/view.jsp?EID=211356
Created: Sep 20, 2000 Modified: 2000-09-20 14:08:56.286
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7) Question
originally posed by Prabhakar Pamula
(http://www.jguru.com/guru/viewbio.jsp?EID=209916
A singly linked list is one that has only a pointer/reference to the next element in the
list. A doubley linked list has both a previous and next pointer/reference.
Comments and alternative answers
In the context of Java collections, the polymorphic algorithms are all supplied by the
various static methods of the java.util.Collections class. Consider, for example, the
method sort(List list). This method is capable of sorting any collection that has
implemented the List interface, and that includes containers of types ArrayList,
LinkedList, Vector, etc.
The objects of a class exhibit natural ordering if the class has implemented the
java.lang.Comparable interface. Such a class must provide an implementation for the
compareTo method -- referred to as the class's natural comparison method -- that
can then be used by the algorithms and the data structures for comparing data
objects. The compareTo method must return a negative integer, a zero, or a positive
integer if the object on which it is invoked is less than, equal to, or greater than the
argument object.
Many of the system supplied classes possess natural ordering. These include String,
Integer, Float, Double, Date, File and many others. For the String class, the natural
order is lexicographic; it is chronological for the Date class; lexicographic on the
pathname for the File class, etc.
The Iterators supported by all the work-horse container classes, such as ArrayList,
LinkedList, TreeSet, and HashSet, are fail-fast. The Iterator type retrofitted to the
older container class Vector is also fail-fast. For associative containers, such as
HashMap and the older HashTable, the Iterator type for the Collections
corresponding to either the keys or the values or the <key, value> pairs are fail-fast
with respect to the container itself. That means that even if you are iterating over,
say, just the keys of the container, any illegal concurrent modifications to the
underlying container would be detected.
One final note regarding iterators versus enumerations: It is also possible to use an
Enumeration object returned by the elements() method for iterating over the older
container types such as Vector. However, Enumerations do not provide a fail-fast
method. On the other hand, the more modern Iterator returned by a Vector's
iterator() and listIterator() methods are fail-fast. Hence, iterators are recommended
over enumerations for iterating over the elements of the older container types.
Since the Vector class implements the List interface, you can call the
Collections.sort() method to sort the elements in place. You can also manually insert
elements into a Vector to keep the vector sorted. Of course, if keeping sorted access
is such a big deal, you should consider using a different, more appropriate data
structure like a TreeSet.
For 1.1 Java users, you'll need to sort the elements yourself. There is no built-in
support for this. A better option might be to sort the elements as you insert each
element.
Stability in sorting becomes an issue for class-type objects with two or more data
members. We'd obviously need to choose a data member whose values will be used
to order the objects for sorting. Let's say we have multiple objects in a list whose
values for the data member chosen for comparison are the same, but whose values
for the other data members are different. A stable sorting algorithm will leave the
original order of such objects untouched.
Stability in sorting, or lack thereof, is best illustrated by comparing the sorted order
obtained through the quicksort algorithm with the sorted order obtained through the
mergesort algorithm. An optimized implementation of quicksort is slightly faster than
an optimized implementation of mergesort but does not guarantee stability. On the
other hand, mergesort guarantees stability.
To show the comparative results obtained with quicksort and mergesort, let's define
the following class:
class Person {
String name;
int rank;
Person( String nam, int r )
{
name = new String( nam );
rank = r;
}
String getName() { return name; };
public String toString() { return name + " " + rank; }
}
We will sort Person objects by using the following Comparator object:
class PersonComparator implements Comparator {
Betelgeuse 0
Betelgeuse 1
Betelgeuse 2
Trillion 0
Trillion 1
Trillion 2
Zaphod 0
Zaphod 1
Zaphod 2
where the name is followed by the associated rank in each Person object.
On the other hand, if we sort the same original list with a quicksort algorithm using
again the name field for comparison, we get
Betelgeuse 0
Betelgeuse 2
Betelgeuse 1
Trillion 2
Trillion 0
Trillion 1
Zaphod 0
Zaphod 2
Zaphod 1
Notice that objects that are equal with respect to the name field are getting shuffled
by the quicksort algorithm.
The quicksort results I showed above were obtained with a C++ program that
invoked the well-known qsort function with the following invocation
Person* perList[9];
with each element of the list instantiated by a statement like
perList[0] = new Person( "Zaphod", 0 );
perList[1] = new Person( "Zaphod", 1 );
...
...
The comparison function needed for the fourth argument of qsort was defined by
What is a WeakHashMap? What is its use and when should you use it?
Location: http://www.jguru.com/faq/view.jsp?EID=229560
Created: Oct 16, 2000 Modified: 2001-04-19 21:00:00.756
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7) Question
originally posed by piyush sheth
(http://www.jguru.com/guru/viewbio.jsp?EID=38282
A WeakHashMap is a special Map implementation where the keys of the map are
stored in a java.lang.ref.WeakReference. By storing the keys in a weak reference,
key-value pairs can dynamically be dropped from the map when the only reference
to the key is from the weak reference. This makes the WeakHashMap an excellent
implementation for a weakly referenced list, where entries that aren't used
elsewhere may be dropped with no side effects. Also, just because a key may be
dropped, doesn't mean it will immediately be dropped. If the system has sufficient
resources, the weak key reference that isn't externally referenced could stay around
for a long time.
For additional information on Reachability, you can find it in the java.lang.ref package
summary.
WeakHashMaps work best when the keys are objects which are equal only to
themselves. This is the default implementation in the Object class and is sometimes
called "identity equality". If the keys implement "value equality" (where the equals
method compares the object's contents, not their references) then you can sometimes
observe odd behavior. In particular, if you attempt to lookup a value using a different
but equal key you may find that the WeakHashMap no longer has a mapping for it.
This would happen if the original key was dereferenced and garbage collected prior to
your search.
In my defense I can only say that I probably only had JDK 1.2.2 to use in my
investigations. I can't be held responsible if Sun changed the implementation.
Besides, I only used ThreadLocal as an example because I can't think of any
other situation where you would want to use a WeakHashMap.
PS - Please forgive the tone of my previous post. I was obviously in a very foul
mood that day. I can't seem to remember what it was that I found so
objectionable in the original answer.
See also...
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7), Jul 24,
2001
What is a weak reference and what are they used fo...
The load factor determines how full a hashtable may get before it expands its
capacity. I think that the comments on the Hashtable API docs explain it very well:
The load factor is a measure of how full the hash table is allowed to get before its
capacity is automatically increased. When the number of entries in the hashtable
exceeds the product of the load factor and the current capacity, the capacity is
increased by calling the rehash method.
Generally, the default load factor (.75) offers a good tradeoff between time and
space costs. Higher values decrease the space overhead but increase the time cost to
look up an entry (which is reflected in most Hashtable operations, including get and
put).
How do you control growth of vectors when their internal arrays are full?
Location: http://www.jguru.com/faq/view.jsp?EID=262290
Created: Nov 24, 2000 Modified: 2000-11-24 21:37:34.895
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7)
The vector constructor can include either an initial capacity or a capacity and growth
increment. When not specified, the initial size of the vector is 10 and growth will
double when necessary. Otherwise, initialize size and growth will grow when needed
as specified by the arguments to the constructor.
If the argument to the constructor is a collection, the initial size of the internal
structure is 10% larger than the collection. Since there is no second argument to
control growth, the capacity will double when necessary.
Within the JavaMail classes there is no support for this. However, once you get the
array of messages back from a folder, you can call the Arrays.sort() method in the
collections framework to sort the messges. Since MimeMessage doesn't implement
Comparable, you'll need to provide your own Comparator specifying how you want
the messages to be sorted.
Comments and alternative answers
Starting with the 1.3 release of Java, the java.lang.String class will only calculate the
hashcode once, when its first needed. Future calls to hashCode() will return the
previously calculated value.
This will cause a stack overflow exception to be generated on calls to methods like
toString() and hashCode(), which recursively call the method on the elements of the
collection.
In order for the Java Collections to work properly (and everything else in Java), the
equals() and hashCode() methods must be compatible. Here, compatible means that
if equals() reports that two instances are the same, then the hashCode() of both
instances must be the same value.
Since Properties extends Hashtable, can I use the Hashtable methods to add
elements to a Properties list?
Location: http://www.jguru.com/faq/view.jsp?EID=302764
Created: Jan 15, 2001 Modified: 2001-01-15 08:17:43.611
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7)
Technically speaking you can. However, you have to make sure you only add key-
value pairs where both are strings. If you add something other than a String, the
listing, loading, and saving methods won't work as expected.
Normally the Java garbage collector plays safe. It will only free up the memory used
by an object when that object can no longer be accessed by the program. Once an
object become impossible to reach it is eligible for collection, and eventually its
memory will be reclaimed.
This eliminates one of the most common programming errors in some other
languages (like C++), where code accidentally tries to access an object that has
been freed. Unfortunately it can lead to another problem, where you leave open a
potential access route to an object that you don't need any more. Memory fills up,
and the program slows down or reports an "Out of Memory" error.
To avoid this, you can be very careful to close off access paths to an object once you
have finished using it. Java 2 introduces another alternative, the weak reference.
Weak references provide access to an object without preventing it from being freed.
When you use a weak reference you have to accept that the object referred to may
have disappeared, which results in the reference being automatically set to null. On
the other hand, the weak reference will not hold the object in memory once it is
inaccessible via normal references (or via "soft" references - see below). Weak
references are not appropriate in all circumstances, but sometimes they can make
code easier to write and understand.
The most common use of weak references is indirect - they are used internally by
the WeakHashMap class. Like HashMap, WeakHashMap associates key objects with
values. However, once the key object becomes inaccessible via stronger references it
becomes eligible for garbage collection. When it is freed, the map entry magically
disappears. The assumption here is that if you are not using the key anywhere other
than in the map you will have no need to look it up, so it should be freed.
Other specialist references are soft references (which inhibit collection until memory
runs short), and phantom references (used for cleanup when objects are freed).
For more detailed (and precise) information, see the java.lang.ref API docs, and also
the article Reference Objects and Garbage Collection at the Sun website.
See also...
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7), Jul 24,
2001
What is a WeakHashMap? What is its use and when sh...
What is the minimum number of key-value pairs for which it makes sense to
use a HashMap, as opposed to using a pair of arrays (one for keys, the other
for values) with brute-force key searches?
Many people often need maps for very small numbers (2-5) of key-value
pairs. When does it make sense to forgo the convenience of the HashMap to
avoid the associated overhead?
Location: http://www.jguru.com/faq/view.jsp?EID=329390
Created: Feb 14, 2001 Modified: 2001-02-14 21:02:25.101
Author: Ryan Breidenbach (http://www.jguru.com/guru/viewbio.jsp?EID=45212)
Question originally posed by Michael Wax
(http://www.jguru.com/guru/viewbio.jsp?EID=242559
Well, is there really that much of a performance loss using a HashMap? There is no
synchronization penalty (unless you impose your own). You can tune the sizing by
adjusting the initial size and load factor. Plus, do you really want to be responsible for
"rolling your own" code to handle the dynamic resizing of the key and value arrays,
inserting/removing data from these arrays, optimizing the searching algorithm, etc.
Yuck!
In general, the performance hit associated with using a general purpose Map (such
as the HashMap) is far outweighed by the benefits of using a simple interface backed
by a tested algorithm.
The only reason I could see wanting to use arrays is to guaruntee the type of your
key/values to add type checking and avoid casting. Still, if this is a critical aspect of
your application, you can wrap your HashMap in another object to provide type-
safety, and the casting overhead should be minimal.
So, to answer your question, I would say that the fewer the key-value pairs you
have, the more reason you have to use a HashMap. Since the fewer the keys, the
faster the search, why not use it for 2-5 key-value pairs. I would think that only
when you get to many pairs (tens of thousands) and there is a performance problem
you should consider an alternative. Basically, exhaust your search of tried-and-true
collections before you try a custom solution. Let other people create these collections
so you can focus on your application.
[Editor note: HashMaps of 10K pairs will function fine, assuming a good hashing
algorithm for hashCode() [with evenly spread out keys]. Keep using it at 10K and
beyond with no problems.]
How does ArrayList increase its capacity?
Location: http://www.jguru.com/faq/view.jsp?EID=333358
Created: Feb 19, 2001 Modified: 2001-02-19 13:32:49.494
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7)
Unlike Vector where you can specify a capacity increment, ArrayList doesn't support
this. Instead, ArrayList will increase capacity by about a half when it runs out of
space. The refernece implementation uses the forumla:
newCapacity = (oldCapacity * 3)/2 + 1
though, this isn't part of the class definition so others can implement it differently.
How can I implement a priority queue in Java? Has anyone created an open
source version?
Location: http://www.jguru.com/faq/view.jsp?EID=335988
Created: Feb 22, 2001 Modified: 2001-07-24 09:53:00.176
Author: michele arpaia (http://www.jguru.com/guru/viewbio.jsp?EID=227978)
Question originally posed by John Zukowski PREMIUM
(http://www.jguru.com/guru/viewbio.jsp?EID=7
As referenced from the Java Collections Clearinghouse, you can find a priority queue
implemented as part of MIT's FLEX compiler imfrastructure. Source code is licensed
under the GNU GPL.
This depends on what version of Java you are using. For JDK 1.2, the size was 101.
For JDK 1.3, the size changed to 11.
Since the elements of a List are objects, in order to make the List multi-dimensional,
each object in the outer list needs to be a List, too. For instance, ...
In a TreeMap, can I use a sorting algorithm other than the natural sorting
for the keys?
Location: http://www.jguru.com/faq/view.jsp?EID=396730
Created: Apr 5, 2001
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7) Question
originally posed by Shailesh Mangal
(http://www.jguru.com/guru/viewbio.jsp?EID=57184
You can pass a Comparator to the TreeMap constructor to use a sorting order other
than the natural order.
Both provide key-value access to data. The Hashtable is one of the original collection
classes in Java. HashMap is part of the new Collections Framework, added with Java
2, v1.2.
The key difference between the two is that access to the Hashtable is synchronized
on the table while access to the HashMap isn't. You can add it, but it isn't there by
default.
Another difference is that iterator in the HashMap is fail-safe while the enumerator
for the Hashtable isn't. If you change the map while iterating, you'll know.
And, a third difference is that HashMap permits null values in it, while Hashtable
doesn't.
Null Values
Author: Sujatha Vengaiah (http://www.jguru.com/guru/viewbio.jsp?EID=1054003),
Feb 5, 2003
Hashtable doesnt allow NULL Values...does it mean for both key and value or just the
key....
Null Values
Author: Sujatha Vengaiah (http://www.jguru.com/guru/viewbio.jsp?EID=1054003),
Feb 5, 2003
Hashtable doesnt allow NULL Values...does it mean for both key and value entry or
just the key entry....
Where can I learn (more) about Java's support for developing multi-
threaded programs?
Location: http://www.jguru.com/faq/view.jsp?EID=431248
Created: May 30, 2001
Author: John Mitchell (http://www.jguru.com/guru/viewbio.jsp?EID=4)
What are the differences between Vector and ArrayList? Which is best to
use?
Location: http://www.jguru.com/faq/view.jsp?EID=433158
Created: Jun 3, 2001
Author: Alessandro A. Garbagnati
(http://www.jguru.com/guru/viewbio.jsp?EID=32727) Question originally posed by
elango maragtham (http://www.jguru.com/guru/viewbio.jsp?EID=248437
Vector and ArrayList are very similar. Both of them represent a 'growable array',
where you access to the elements in it through an index.
ArrayList it's part of the Java Collection Framework, and has been added with version
1.2, while Vector it's an object that is present since the first version of the JDK.
Vector, anyway, has been retrofitted to implement the List interface.
The main difference is that Vector it's a synchronized object, while ArrayList it's not.
While the iterator that are returned by both classes are fail-fast (they cleanly thrown
a ConcurrentModificationException when the orignal object has been modified), the
Enumeration returned by Vector are not.
Unless you have strong reason to use a Vector, the suggestion is to use the ArrayList.
Comments and alternative answers
OnJava.com article...
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7), Jun 18,
2001
For additional information, you can read an article comparing the performance at The
Performance of Java's Lists.
Not Satisfied
Author: kapil pruthi (http://www.jguru.com/guru/viewbio.jsp?EID=909671), Jun 11,
2002
totally not satisfied with the answer provided.please elaborate..
Java.util.Collection
Author: Rohit Anand (http://www.jguru.com/guru/viewbio.jsp?EID=1088769), Oct
31, 2003
one more difference can be ArrayList implements Iterator Interface for traversing
While Vector implements Innumerator Interface for traverse.
Another Difference
Author: shreehari gopal (http://www.jguru.com/guru/viewbio.jsp?EID=1163112),
May 18, 2004
There is also an another difference between Vectors and ArrayLists, not very
important but it will be an added advantage. If we insert an element beyond the border
of a vector it will increases the size by double of its orginal size.but an ArrayList will
increases its size by 50% of the orginal list
Instead of having the Person class implement the Comparable interface, you could
delegate the comparing to another class. Perhaps you could have a
PersonComparator interface that you could implement for the various types of
comparisons. For example:
public interface Person {
public String getName();
public int getAge();
}
Additional Information
Author: christophe tcheng (http://www.jguru.com/guru/viewbio.jsp?EID=269636), Jul
2, 2001
You should consider implementing the Comparator interface (java.util), and not your
own PersonComparator interface. Indeed, this interface is known used in the JDK,
and therefore you will be able to sort arrays or collections very easily.
Collections.sort( ... );
Arrays.sort( ... );
Christophe.
You can hide the implementation details inside the class and just change the way the
data is sorted with get/set methods.
..
public static final int NAMESORT = 0;
public static final int AGESORT = 0;
..
Not
...
private static final int NAMESORT = 0;
private static final int AGESORT = 1;
...
Cat
You can get situations where a.compareTo(b) and b.compareTo(a) are inconsistent
(if a and b were called with different sort methods).
Good point. My response would be to make certain that you could only
compare apples with apples.
One way to handle this would be to override the compareTo method so that it
used the getSort method to check the sort type and threw an
IllegalArgumentException if they where different.
It is nice to have a general purpose framework like this. It certainly saves you
from having to do your own sorting algorithms 95% of the time. Which for
mere mortals is a real pain.
Cat
If you have two arrays in memory with the same elements, and ask
first.equals(second), this does not do an element-by-element comparison. Instead, it
behaves just like Object's equals() method, essentially asking if the variables point to
the same place in memory:
int a[] = {1, 2, 3};
int b[] = {1, 2, 3};
// This prints false
System.out.println(a.equals(b));
To check for equality of two arrays, use Arrays.equals().
// This prints true
System.out.println(Arrays.equals(a,b));
Comments and alternative answers
How can I retrieve the items in my HashSet / HashMap in the order they
were added?
Location: http://www.jguru.com/faq/view.jsp?EID=456424
Created: Jul 17, 2001
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7)
Prior to Java 1.4, you had to manage a separate insertion order list yourself. Starting
with Java 1.4, you can use the new LinkedHashMap / LinkedHashSet classes. The
iterators you get back from them return the items in insertion order.
Comments and alternative answers
Give me an example
Author: James Liu (http://www.jguru.com/guru/viewbio.jsp?EID=1032513), Dec 1,
2002
Please give me an examole for the answer.
An Example
Author: Shiladitya Sircar
(http://www.jguru.com/guru/viewbio.jsp?EID=1173860), May 26, 2004
LinkedHashMap is essentially similar to the LinkedHashSet, its just that you need
a key/value pair for each element. Example :
String Englishmonths[] = new DateFormatSymbols().getMonths();
String frenchMonths[] = new
DateFormatSymbols(Locale.ITALIAN).getMonths();
Map orderedMap = new LinkedHashMap();
for (int i = 0, n = months.length; i & lt; n; i++)
{
orderedMap.put(months[i], italianMonths[i]);
}
Check to see that iterators for this are aware of the insertion order. So you can
walk through the values of the insertion order.
Collection values = orderedMap.values();
for (Iterator i = values.iterator(); i.hasNext();
{
System.out.println(i.next()));
}
How can you get the hash code for an instance of a class if the class
overrode hashCode()?
Location: http://www.jguru.com/faq/view.jsp?EID=470503
Created: Aug 7, 2001
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7)
The System class method identityHashCode() allows you to get this information:
HashCode
Author: Parag Agarwal (http://www.jguru.com/guru/viewbio.jsp?EID=1136228), Dec
30, 2003
YourClass obj;
System.out.println(obj.hashCode());
How can I easily shift the elements in a List / Vector such that all the
elements rotate n elements?
Location: http://www.jguru.com/faq/view.jsp?EID=483403
Created: Aug 24, 2001
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7)
The Java 1.4 API adds a rotate() method to the Collections class: rotate(List
list, int distance) that will shift the elements for you.
The 1.4 version of Collections has a swap() method to do this for you. However, for
earlier version of Java, you can swap two elements w/o an intermediate variable
with:
list.set(index1, list.set(index2, list.get(index1)));
This works because the set() method returns the original element.
What's the purpose of the IdentityHashMap?
Location: http://www.jguru.com/faq/view.jsp?EID=483413
Created: Aug 24, 2001
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7)
The IdentityHashMap uses == for equality checking instead of equals(). This can be
used for both performance reasons, if you know that two different elements will
never be equals and for preventing spoofing, where an object tries to imitate
another.
Prior to Java 1.4, any conversion had to be manually done. With the introduction of
1.4, you can call Collections.list(enumeration) to automatically convert the
Enumeration to an ArrayList.
Basically, you can't directly do this. What you can do is get the Collection of
values() back from the map and create a sorted collection, or maintain two maps,
one in each direction, and keep the second map sorted by being a TreeMap. Which
you use depends on the frequency you must sort the elements.
Comments and alternative answers
Sorted Hashtable
Author: Sualeh Fatehi (http://www.jguru.com/guru/viewbio.jsp?EID=404605), Jun 4,
2002
Here is something you may be able to use - you will have to do your own debugging,
though ;-)
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
/**
* @author Sualeh Fatehi
*/
public class SortedHashtable
{
return vectSortedHashtable.elements();
vectSortedHashtable.addElement(key);
hashSortedHashtable.put(key, value);
vectSortedHashtable.remove(key);
hashSortedHashtable.remove(key);
} // end SortedHashtable
Can u provide me some simpler solution to get the values from a hash map? The
method u hav given is quiet confusing. My need is to read a text file which can be
used as a cinfig file. The file will hav some options as true and false or something
like that. so m looking for a solution which is smaller and as desired. Thnks
Sorted Hashtable
Author: Sualeh Fatehi (http://www.jguru.com/guru/viewbio.jsp?EID=404605), Jun 4,
2002
Here is something you may be able to use - you will have to do your own debugging,
though ;-)
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
/**
* @author Sualeh Fatehi
*/
public class SortedHashtable
{
return vectSortedHashtable.elements();
}
public void clear()
{
vectSortedHashtable.addElement(key);
hashSortedHashtable.put(key, value);
vectSortedHashtable.remove(key);
hashSortedHashtable.remove(key);
}
} // end SortedHashtable
If you want to maintain a sorted hashtable - either by key or object (item) then you
should really extend hashtable and re-implement only the methods that you need
to. Call the super methods where you need to. This way it will work with existing
code that expects a hashtable. As follows...
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import java.lang.StringBuffer;
}//SortedKeyHashtable
The method that is shown is quiet confusing... can u suggest some simple method to
get the values ? thnks
In case of Vector the method addAll garantees the unicity of the added elements in the
Vector. If not can you help me with an efficient source code? Thanks.
Where can I find performance comparisons between the different collection
implementations?
Location: http://www.jguru.com/faq/view.jsp?EID=507239
Created: Sep 30, 2001 Modified: 2001-09-30 15:36:34.355
Author: Luigi Viggiano (http://www.jguru.com/guru/viewbio.jsp?EID=101985)
Question originally posed by John Zukowski PREMIUM
(http://www.jguru.com/guru/viewbio.jsp?EID=7
An interresting benchmark about Java collections has been done by Bruce Eckel's in
his (online) book Thinking in Java. You'll find them in Chapter 9.
Comments and alternative answers
Performance benchmaks
Author: Naren Varma (http://www.jguru.com/guru/viewbio.jsp?EID=750962), Feb 7,
2002
You can also find performance benchmarks in the website www.precisejava.com
Performance benchmaks
Author: Naren Varma (http://www.jguru.com/guru/viewbio.jsp?EID=750962), Feb 7,
2002
You can also find performance benchmarks in the website www.precisejava.com
Performance benchmaks
Author: Naren Varma (http://www.jguru.com/guru/viewbio.jsp?EID=750962), Feb 7,
2002
Just keep getting the last key and the head map before it:
if (!map.isEmpty()) {
Object last = map.lastKey();
boolean first = true;
do {
if (!first) {
System.out.print(", ");
}
System.out.print(last);
last=map.headMap(last).lastKey();
first=false;
} while (last != map.firstKey());
System.out.println();
}
(Taken from my Java Collections book.)
Just keep getting the last element and the head set before it:
if (!set.isEmpty()) {
Object last = set.last();
boolean first = true;
do {
if (!first) {
System.out.print(", ");
}
System.out.print(last);
last=set.headSet(last).last();
first=false;
} while (last != set.first());
System.out.println();
}
Comments and alternative answers
Alternative?
Author: Troy Molander (http://www.jguru.com/guru/viewbio.jsp?EID=508870), Oct
12, 2001
John,
Can you comment on the pro's and con's to this approach vs. the approach you
presented:
List list = new LinkedList(set);
Collections.reverse(list);
for (Iterator it = list.iterator(); it.hasNext();){
System.out.println(it.next());
}
Thanks.
repeating ".headset()"
Author: zira mona (http://www.jguru.com/guru/viewbio.jsp?EID=525506), Oct 19,
2001
If the implementation of the container is buggy, it can cause each head set have a
pointer to its parent set, and this can lead to an almost infinite chain of references.
beware.
There is no direct support for this. You'll need to create your own caching
mechanism. For instance, as you go through the Iterator the first time, add the
elements to a LinkedList. Then, you can just get an Iterator from the LinkedList for
the second pass through.
• LinkedHashSet
• LinkedHashMap
• IdentityHashMap
• RandomAccess
First you need to convert the array to a Collection. This can be done with
Arrays.asList(objectArray). Once you have the array as a List, you can add it to
another Collection with theCollection.addAll(theList).
(It doesn't -really- prove that it's thread-safe, since merely using synchronized
doesn't guarantee thread safety -- the method could call a non-thread-safe shared
object, for instance -- but it's a good indication.)
This is better than using a FileInputStream, because you are loading the file within
the archive as it was a resource. You should use this.getClass().getClassLoader() to
use the same ClassLoader as the one used the servlet container to load your
JSP/Servlet. This code is snipped from a JSP page inside Tomcat.
Try this:
Properties prop = new Properties();
FileOutputStream output = new FileOutputStream("Test.properties");
prop.store(output,"my testproperties");
output.flush();
output.close();
You'll need to catch an IOException.
What happens if two threads perform a get of one hashmap at the same
time?
Location: http://www.jguru.com/faq/view.jsp?EID=1048741
Created: Jan 21, 2003
Author: Muruganantham Mani
(http://www.jguru.com/guru/viewbio.jsp?EID=1041080) Question originally posed
by Enrique Monton (http://www.jguru.com/guru/viewbio.jsp?EID=755656
Synchronization needs to be done only when there is a chance of changing the data
from different threads simultaneously. In your case, it is simply going to be a read,
the synchronization is not required. If you need to remove or modify the values in
the hashmap, then you [may] need to synchronize that.
But let's say, we have several threads trying to get objects from the same HashMap
using different keys:
... hm.get("21");
... hm.get("10");
... hm.get("44");
at the same time.
If we are sure that get method is implemented as "atomic" operation that approach is
probably OK. But let's say, that get method is implemented to first save the key we
provided as a private field of HashMap internal state and then makes the search. In
this case results could be unpredictable - while looking for the object with the key
"21" we might get back the object corresponding to the key "44".
So to be sure that the get method returns proper value corresponding to the key we
have to be sure that it is NOT modifying internal state of the shared HashMap object
while searching. We can only hope for that as JDK API says nothing about it, just
"implementation is not synchronized".
If multiple threads access this map concurrently, and at least one of the threads
modifies the map structurally, it must be synchronized externally. (A structural
modification is any operation that adds or deletes one or more mappings; merely
changing the value associated with a key that an instance already contains is not a
structural modification.)
Still it is not lucid - at list for me - whether those explanations provided by JDK
should be considered as examples of "implementation is not synchronized" or
clarifications on how exactly "implementation is not synchronized".
The Arrays class provides the opposite. A way to turn an array into a List using the
List<T> asList(Array[] a) method. The List returned is of a fixed length with any
attempts to add an element throwing an UnsupportedOperationException.
import java.util.*;
public class G{
public static void main(String[] args){
List<String> sun = new ArrayList<String>();
sun.add("Feel");
sun.add("the");
sun.add("power");
sun.add("of");
sun.add("the");
sun.add("Sun");
String[] s1 = sun.toArray(new String[0]); //Collection to array
for(int i = 0; i < s1.length; ++i){
String contents = s1[i];
System.out.print(contents);
}
System.out.println();
List<String> sun2 = Arrays.asList(s1); //Array back to Collection
for(String s2: sun2){
String s3 = s2; System.out.print(s3);
}
//sun2.add(new String("Hello")); // throws
UnsupportedOperationException
}
}
The following is a short list of the constructors provided by some of the concrete
Classes of the JCF (Java Collections Framework), which enable the creation of a
Collection based an another implementation.
Creating a Collection based on another Collection is quite easy. The hard part is
knowing which Collection to use based on performance and other issues.
For example the ArrayList created will contain the same elements in the same order
as the first ArrayList created.
for(String s : slist){
System.out.print(s + "\t");
}
System.out.println();
List<String> s2list = new ArrayList<String>(slist);
for(String s : s2list){
System.out.print(s + "\t");
}
When creating a Set based on an existing List the Set will be void of duplicates.
List<String> slist = new ArrayList<String>();
slist.add("g");
slist.add("a");
slist.add("d");
slist.add("a");
slist.add("f");
slist.add("e");
slist.add("c");
slist.add("b");
for(String s : slist){
System.out.print(s + "\t");
}
System.out.println();
Set<String> s2set = new TreeSet<String>(slist);
for(String s : s2set){
System.out.print(s + "\t");
}
How can I define my own Comparable type so that it can be naturally sorted
within a List?
Location: http://www.jguru.com/faq/view.jsp?EID=1251044
Created: Jun 29, 2005
Author: Brandon Rohlfs (http://www.jguru.com/guru/viewbio.jsp?EID=1245666)
When taking a peek at the Java docs you will notice certain classes implement an
interface named Comparable. Take a look at some of the subclasses of Number such
as Byte, Integer, Long, Float or some of the classes like String and Date. What the
Comparable interface provides is a way for a class to be sorted by it's natural
ordering. So what do we mean by natural ordering? Depending on the type wishing
to be sorted the natural ordering can be different things. If we are sorting Strings the
ordering is lexicographic or alphabetic if we are sorting Dates the ordering is
chronological if we are sorting Integers the ordering is numerical.
Comparable only contains one method that needs to be implemented by the class
wishing to be sorted naturally. Remember if you try and sort a list that contains
elements that do not implement the Comparable interface then Collections.sort() will
throw an exception specifically a ClassCastException.
Collections.sort(alpha);
System.out.println(alpha);
}
private String letter;
public Alpha(String letter){
if(letter == null){throw new NullPointerException();}
this.letter = letter;
}
public String toString(){return letter;}
public boolean equals(Alpha a){
if(!(a instanceof Alpha))
return false;
return letter.equals(a.letter);
}
public int compareTo(Alpha a){
int i = letter.compareTo(a.letter);
return i;
}
}
More complex examples might included sorting on multiple fields. Most things that
you would have to sort probably have more then one part like a name for instance
(First:Middle:Last) or maybe you have to sort in (Brand:Model) order.
import java.util.*;
Collections.sort(car);
System.out.println(car);
}
private String brand;
private String model;
public Car(String brand, String model){
if(brand == null || model == null){throw new NullPointerException();}
this.brand = brand;
this.model = model;
}
public String toString(){return brand + " " + model;}
public boolean equals(Car car){
if(!(car instanceof Car))
return false;
boolean samebrand = brand.equals(car.brand);
return samebrand != true ? samebrand: model.equals(car.model);
}
public int compareTo(Car car){
int i = brand.compareTo(car.brand);
return(i != 0 ? i : model.compareTo(car.model));
}
}
One of the biggest additions since the creation of the Collections framework is
Generics.This long awaited update to the type system is a welcomed feature, which
C++ developers have had in their toolbox for years using the STL. A generic type is
defined using one or more type variables with it's contained methods using that type
variable as a place holder to mark a parameter or return type. For instance the
interface List has now been defined as.
So you might ask. What are Generics and why should I use them? Generics are a
way to restrict a data structure to hold only a specific type thus providing compile
time type checking. One of the added bonuses is that it is no longer necessary to
cast a returned Object to a specific type because the compiler is aware of what type
is being held by the Collection and what type is to be returned.
// java 5
Set<String> s = new SortedSet<String>();
s.addElement(new String("String Type"));
String s = s.get(0); // no cast required!
Having a type safe system not only obviates the need to cast to a specific type but
shields the programmer against miss-casting or casting to an unrelated type at
runtime.
Generics do not share some of the things that are commonly held true in the Java
language and one of them is subtyping. One would assume the following perfectly
legal since it is true that Object is a supertype of String. But the following is in fact
illegal and will cause a compile time error.
Wild Cards
Wild Cards represent what is called "the unknown type". Essentially they can be
thought of as the supertype of any Collection. Wildcards allow some flexibility in
certain situations where it is needed that a type be abstracted out. For instance what
if we define the following method, printSet(Collection<Object> x). We just saw in the
previous example that E<Object> is not the super type of E<String> or any other
type for that matter. In this case we can change the printSet's parameter to
Collection<?>. This allows us to pass in E<X> where X is any type.
When working with wildcards it is always legal to read and assign the contents to an
Object type
assigning values is another matter. The add() method takes an argument of type E
which is the type that the Collection is to hold. Any type wishing to be added to the
Collection would have to be of the same type. Since<?> represents an unknown type
it is impossible to determine what the type parameter of the collection represents.
Bounded Wildcards
import java.util.*;
class Printer{
public void print(String s){
for(int i = 0; i < s.length(); i++){
System.out.print(s.charAt(i));
}
}
}
class ReversePrinter extends Printer{
public void print(String s){
for(int i = s.length() - 1 ; i >= 0; i--){
System.out.print(s.charAt(i));
}
}
}
public class G{
public static void main(String[] args){
String s = "Nothing like a good cup of Java in the morning!";
List<Printer> l = new ArrayList<Printer>();
l.add(new Printer());
printElements(l,s);
List<ReversePrinter> rl = new ArrayList<ReversePrinter>();
rl.add(new ReversePrinter());
printElements(rl,s);
}
public static void printElements(List<? extends Printer> l, String s){
Printer printer = l.get(0);
printer.print(s);
System.out.println();
}
}
The Collections class which can be found within the java.util namespace provides two
methods which suffle the elements of a Collection.
How can i tell if two Collections contain the same elements or have no
elements in common?
Location: http://www.jguru.com/faq/view.jsp?EID=1255577
Created: Jul 28, 2005
Author: Brandon Rohlfs (http://www.jguru.com/guru/viewbio.jsp?EID=1245666)
boolean containsAll(Collection<?> c)
boolean disjoint(Collection<?>c1 Collection<?>c2)
Since containsAll(Collection<?> c) is defined within the Collection interface all
concrete implementations will be able to use this method. disjoint(Collection<?>c1
Collection<?>c2) is defined within the Collections class.
In order to traverse a List backwards a ListIterator must be used. The List interface
provides a method, which returns a ListIterator.
ListIterator<E> listIterator()
boolean hasPrevious()
E previous()
Since ListIterator extends the Iterator interface forward direction is still possible via
Iterators methods.
boolean hasNext()
E next()
import java.util.List;
import java.util.ArrayList;
import java.util.ListIterator;
public class {
public static void main(String[] args){
List<String> slist = new ArrayList<String>();
slist.add("1");
slist.add("2");
slist.add("3");
slist.add("4");
ListIterator i = slist.listIterator();
while(i.hasNext()){
System.out.print(i.next());
}
System.out.println();
while(i.hasPrevious()){
System.out.print(i.previous());
}
}
}
Comments and alternative answers
The Map interface defines a method named keySet() which concrete classes such as
HashMap and TreeMap implement. Depending on the implementation on which
keySet() is invoked the returned Set might not contain it's elements (keys) in sorted
order. For instance the HashMap class makes no guarantees as to the order of the
elements contained within. Whereas the TreeMap class does guarantee element
ordering since it implements the SortedMap interface.
The Collections class provides a method which returns the number of times an Object
appears within a given Collection.
The easiest way to obtain a Map Entry or (key-value pair) is by invoking the following
method provided by the Map interface.
Set<Map.Entry<K,V>> entrySet();
The entrySet() method returns a Set which is populated with Map.Entry objects. The
only way to obtain a reference to a Map.Entry is by using an Iterator on the returned
Set view. Once a reference to a Map.Entry is obtained the follow methods can be
invoked which return the key and value corresponding to the entry.
K getKey()
V getValue()
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.Iterator;
Set s = empmap.entrySet();
for(Iterator i = s.iterator();i.hasNext();){
Map.Entry me = (Map.Entry)i.next();
System.out.println(me.getKey() + " : " + me.getValue());
}
}
}
Comments and alternative answers
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.Iterator;
Finding the maximum element within a Collection is easy. The following method can
be used which can be found within the Collections class.
If the element type being store within the Collection is user defined, implementation
of the Comparable interface must be provided.
import java.util.Set;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;