Object []toArray()

okay, i just frankly don't really know what this is , but i would like to make an object array from my linked list.I looked in the API documentastion, but i jsut didn't understatnd it. How would i write a method that would make an arry of the a linked list with lets say 10 nodes, for example
any help would be appreciated!!

Object[] anArray = listOne.toArray();
Object[] anotherArray = listTwo.toArray();
System.out.println("The arrays have " + anArray.length + " and " + anotherArray.length + " elements");Still not clear on some aspect of this, or does that make sense now?

Similar Messages

  • Can anyone clarify me about the api Object[] toArray(Object[])

    There are two apis in Collections framework to convert the Collection elements into an array
    1. Object[] toArray()
    2. Object[] toArray(Object[])
    Can some one explain me what does the second api - Object[] toArray(Object[]) does ?

    Just read the javadoc API of the Collection interface: toArray() just returns an Object[]. But if you need for example a String[] as result use
    String[] sa = o.toArray(new String[0]);

  • Implementation of toArray(Object[] a)

    I'm having trouble grasping one small aspect of the method, specifically:
    "Otherwise, a new array is allocated with the runtime type of the specified array and the size of this collection."
    As I understand it, if a user passes in an array of String objects and the array is not long enough, I need to allocate a new array of String objects, and not just simply an array of Objects. How exactly would I go about instantiating an array of objects of a specific type that is determined at runtime?

    You can look in the src.zip to see how this is done for ArrayList:
    public Object[] toArray(Object a[]) {
        if (a.length < size)
            a = (Object[])java.lang.reflect.Array.newInstance(
                                    a.getClass().getComponentType(), size);
        System.arraycopy(elementData, 0, a, 0, size);
        if (a.length > size)
             a[size] = null;
        return a;
    }

  • Please help- How can I publish an object with irregular getter/setter metho

    I'm encountering a problem with weblogic 9.2 web service. Here it is the description:
    I have a java class which doesn't expose getter/setter method, Like this:
    public class MyEntityList
    implements Cloneable, Serializable
    private Map subEntityMap;
    public final Object[] toArray()
    return subEntityMap.values().toArray();
    public final Iterator subEntities()
    return subEntityMap.values().iterator();
    public final GFIBaseSubEntity getSubEntityByKey(String key)
    if(key == null)
    return null;
    else
    return (GFIBaseSubEntity)subEntityMap.get(key);
    public final void setSubEntity(GFIBaseSubEntity entity)
    subEntityMap.put(entity.getKey(), entity);
    When I publish this object out, the web service engine will not parse the value in this object for it hasn't getter methods. But I do need the value in it, and I can't change the class for it's from external system. Can I define my own serializer class to process the MyEntityListin weblogic 9 or 10? Or is there any way to process this case?
    Thanks in advance

    In 1.4 you have ImageIO available ... javax.imageio.ImageIO.write is the method to call.
    - David

  • Writing the toArray method

    This is a question from a quiz of mine from a course from last semester. I am trying to work it to help prepare for an exam.
    I am to write the toArray method to add the elements of a list to an array of the exact same size. I am to do this using an iterator.
    Here is what I had done. This is suppose to be in a "driver" class.
    ListInterface list = new List??Based(); //The type of implementation shouldn't matter
    Object[] = toArray(list)
    private static Object[] toArray(ListInterface list)
         Iterator iter = list.iterator();
         int size = 0;
         while(iter.hasNext())
              size++;
              iter.next();
         int index = 0;
         Object[] temp = new Object[list.size()];
         while(iter.hasNext())
               array[index] = item.next();
               index++;
    }I am open to any constructive criticism. This is as far as I have gotten.

    Here is my final code for the proposed problem:
    ListInterface list = new List??Based();
    Object [] array = toArray(list);
    *Returns an Object array containing the exact elements of a given list. <br>
    *Preconditions: A list of elements to insert into an array. <br>
    *Postconditions: An array of the elements from the given list. The list will not reference the array, therefore the array
    * is an independent copy of the elements from the given list. <br>
    *Throws: none <br>
    private static Object[] toArray(ListInterface list)
         Iterator iter = list.iterator(); //to traverse the list
         Object tempArray = new Object[list.size()]; //creates a new array of the exact same size of the list
         while(iter.hasNext()) //test to make sure we have not reached the end of the list
              int index = 0; //the starting index of the array to add elements
              array[index] = iter.next(); //gets the item and places into the array
              index++; //increments index by 1 to move to next place of insertion in the array
         }// end while
         return tempArray; //returns the new array to the calling method
    }// end toArray    

  • Collection.toArray

    Why does the Collection<E> interface have a method
    Object[] toArray()instead of
    E[] toArray()?
    I bet there is a reason, but it is not obvious to me what the reason might be ...

    If you tried to compile that class, I believe that the second, third, and sixth lines will emit compiler errors.
    I don't believe that it is legal to declare an array of E's.It compiles. Look at Collection.toArray(T[]) for another example, or section 7.3 in the generics tutorial.
    I guess the problem with the method in question, if defined as E[] toArray(), is that it should return an array of the collection's element type in order to be correct (do what it says it does). So:
    List<Something> list = new ArrayList<Something>();
    list.toArray();  // <--- would return a Something[]But, if you replace Something with a parameterized type, you can't have an array of it. So you can have a List<Filter<String>>, but what does its toArray() method return? It could return an array of the raw type (Filter) of E but how do you declare that?
    CollImpl ducks around this somewhat, because you can't create one with E as a parameterized type in the first place, due to the constructor. But the contracts java.util.Collection specifies should be able to be upheld by all implementations.
    That's the issue as I see it anyway, but maybe there's more to it.
    Mark

  • Is this a bug in Java, or am I doing something wrong?

    I have a Vector which I want to convert to an array, so I wrote my code something like this:
    MyObject a = new MyObject("A");
    MyObject b = new MyObject("B");
    MyObject c = new MyObject("C");
    MyObject d = new MyObject("D");
    Vector v = new Vector();
    v.add(a);
    v.add(b);
    v.add(c);
    v.add(d);
    MyObject[] list = new MyObject[v.size()];
    list = (MyObject[]) v.toArray();This should work, however it gives me a ClassCastException at runtime. Of course, I found ways around it, like using
    v.toArray(list);But using the method this way does not make any sense because according to the API it is not void, but supposedly returns another array of Objects in addition to filling up the array which you pass to it.
    Does anyone know the correct way to use the toArray() method, or it's even more mysterious overloaded companion, toArray(Object[] a)?

    With regards to the Vector.toArray() method that takes an Object[] as an argument, you would normally use it this way:
    Vector vector = <whatever>; // contains only instances of MyClass
    MyClass[] array = (MyClass[])vector.toArray(new MyClass[vector.size]);While you're right that if you declare the array first and then simply pass it to the toArray() method that the array will get filled with the appropriate values. However, the array that is returned is not necessarily the array that was passed in. If the array that is passed in is shorter than the number of elements in the Vector, a new array of the same type as the one passed in is allocated and it is that array which is returned. The API only says that an array is returned, not the original one. Here is the source code for the toArray() method for you to look at:
        public synchronized Object[] toArray(Object a[]) {
            if (a.length < elementCount)
                a = (Object[])java.lang.reflect.Array.newInstance(
                                    a.getClass().getComponentType(), elementCount);
         System.arraycopy(elementData, 0, a, 0, elementCount);
            if (a.length > elementCount)
                a[elementCount] = null;
            return a;
        }Shaun

  • Command link / button action is not taking place if i use it in iterator.

    Hi,
    I am new to ADF, i am facing 1 issue while implementing ADF mobile browser application.
    Issue: command link / button action is not taking place if i use it in iterator. its just refreshing the page it self and displaying as no records.
    Scenario is i am populating the search results in results page from search page using iterator, i want to get the complete details in different page (results page -> details page) .
    I have tried in different ways.like
    case1:
    <tr:panelGroupLayout id="pgl2" layout="vertical" styleClass="af_m_panelBase">
    <tr:panelHeader text="#{classviewBundle.SEARCH_RESULTS}" id="ph1"/>
    <tr:iterator id="i1" value="#{bindings.SubjectVO1.collectionModel}" var="subject"
    varStatus="subIndx" rows="100">
    <tr:panelBox text="#{subject.Subject} #{subject.CatalogNbr} - #{subject.CourseTitleLong}"
    styleClass="af_m_listingPrimaryDetails" id="pb1">
    <f:facet name="toolbar"/>
    <tr:table var="ssrClass" rowBandingInterval="1" id="t1" value="#{subject.children}"
    varStatus="clsIndx" rowSelection="none"
    binding="#{SessionBean.subjectTable}" verticalGridVisible="true"
    emptyText="No Records" width="100%">
    <tr:column id="c9" sortable="false" styleClass="width:100%">
    <*tr:commandLink text="Section: #{ssrClass.ClassSection}-#{ssrClass.SsrComponentLovDescr} (#{ssrClass.ClassNbr})"*
    id="commandLink2" styleClass="af_m_listingLink"
    *action="#{pageFlowScope.BackingBean.searchaction}"></tr:commandLink>*
    //remaining code
    in this case commandlink action is not able to invoke serachaction() method
    case 2:
    <tr:commandLink text="Section: #{ssrClass.ClassSection}-#{ssrClass.SsrComponentLovDescr} (#{ssrClass.ClassNbr})"
    id="commandLink2" styleClass="af_m_listingLink"
    action="classdetails}"></tr:commandLink>
    in this case its not able to navigate to classdetails page.
    I gave correct navigation cases and rules in taskflow,but its working fine when the command link is out of iterator only.
    i tried with actionlistener too.. but no use.. please help me out of this problem .
    *Update to issue:*
    The actual issue is when i use command link/button in an table/iterator whose parent tag is another iterator then the action is not taking place.
    the structer of my code is
    < iterator1>
    #command link action1
    < iterator2>
    #command link action2
    </ iterator2>
    < /iterator1>
    #command link action1 is working but "#command link action2" is not...
    Thanks
    Shyam
    Edited by: shyam on Dec 26, 2011 5:40 PM

    Hi,
    To solve my problem I used a af:foreach instead.
    <af:forEach items="#{viewScope.DataBySubjectServiceBean.toArray}" var="text">
    <af:commandLink text="#{text.IndTextEn}" action="indicator-selected" id="cl1">
    <af:setActionListener from="#{text.IndCode}" to="#{pageFlowScope.IndicatorCodeParam}" />
    </af:commandLink>
    </af:forEach>
    By the way you need to convert the iterator to an Array using a ManagedBean.
    public Object[] toArray() {
    CollectionModel cm = (CollectionModel) getEL("#{bindings.TView1.collectionModel}");
    indicators = new Object[cm.getRowCount()];
    for(int i=0;i<cm.getRowCount();i++){
    indicators[i] = cm.getRowData(i);
    return indicators;
    public static Object getEL(String expr) {
    FacesContext fc = FacesContext.getCurrentInstance();
    return fc.getApplication().evaluateExpressionGet(fc,expr,Object.class);
    Hope that helps-
    Edited by: JuJuZ on Jan 3, 2012 12:23 AM
    Add getEL Method

  • Problem in converting vector to array of strings

    hi
    i am having a vector which in turn contains hashtable as elements
    Vector v=new Vector()
    Hashtable ht=new Hashtable();
    v.add(ht.add("key1",value1))
    v.add(ht.add("key2",value2))
    v.add(ht.add("key3",value3))
    v.add(ht.add("key4",value4))now i am trying to conver this vector in to a array of string like
    String[] str=(String[])v.toArray(new String[v.size()]);but i am getting java.lang.ArrayStoreExceptioncan anybody help me plz
    Thanks

    Hi,
    The api for public Object[] toArray(Object[] a) says
    Returns an array containing all of the elements in this Vector in the correct order; the runtime type of the returned array is that of the specified array.
    ArrayStoreException will be thrown if the runtime type of a is not a supertype of the runtime type of every element in this Vector.
    The runtime type of the elements of the vector is Hashtable.
    Because String is not a supertype of Hashtable the ArrayStoreException is thrown.

  • Variable number of two dimensional arrays into one big array

    I have a variable number of two dimensional arrays.
    The first dimension is variable, the second dimension is always 7.
    i.e.:
    Object[][] array0 = {
    {"tim", "sanchez", 34, 175.5, "bla", "blub", "[email protected]"},
    {"alice", "smith", 42, 160.0, "la", "bub", "[email protected]"},
    Object[][] array1 = {
    {"john", "sdfs", 34, 15.5, "a", "bl", "[email protected]"},
    {"joe", "smith", 42, 16.0, "a", "bub", "[email protected]"},
    Object[][] arrayi = ...I'm generating these arrays with a for-loop:
         for (int i = 0; i < filter.length; i++) {
              MyClass c = new MyClass(filter);
              //data = c.getData();
    Where "filter" is another array which is filled with information that tells "MyClass" how to fill the arrays.
    "getData()" gives back one of the i number of arrays.
    Now I just need to have everything in one big two dimensional array.
    i.e.:Object[][] arrayComplete = {
    {"tim", "sanchez", 34, 175.5, "bla", "blub", "[email protected]"},
    {"alice", "smith", 42, 160.0, "la", "bub", "[email protected]"},
    {"john", "sdfs", 34, 15.5, "a", "bl", "[email protected]"},
    {"joe", "smith", 42, 16.0, "a", "bub", "[email protected]"},
    Any idea on how to accomplish this? It's blowing my mind right now.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

    Just brainstorming here:
    Why not put your actual data in a class and store that in a LinkedList (so you know the total number of elements for your multi-dimensional array). Then initalize your multi-dimensional array and populate it? Haven't tested the following, but thinking something along the lines of
    public class MyData {
         //data here
         public Object[] toArray() {
              //something similar to this
              return new Object[] = {"tim", "sanchez", 34, 175.5, "bla", "blub", "[email protected]"};
    LinkedList<MyData> data = new LinkedList<MyData>();
    data.add(mydata1);
    //however many times you need
    Object[][] arrayComplete = new Object[data.size()][7];
    for(int i = 0; i < data.size(); i++) {
         arrayComplete[i] = data.removeFirst().toArray();
    }Another option for knowing how many rows you would need might be using something like:
    int rows = 0;
    rows += array1.length;
    rows += array2.length;
    //etc...But is not entirely useful if you don't know how many variable arrays you have (although reflections might help if the name of the array variable is incremented systematically, someone told me earlier to avoid reflections since it could make debugging a LOT more difficult).
    Edited by: bogdana on Apr 1, 2010 10:38 AM

  • Need Help with linkedList

    I have to write a program for my class... But I'm having trouble... if some one can help me to write the add, addall method, to print...
    where if the code... Thank You
    * SinglyLinkedList.java
    * An implementation of the List interface using a
    * singly linked list.
    * (P) 2000 Laurentiu Cristofor
    * Modified (slightly) for s03 by D. Wortman
    * Modified by Ennio Bozzetti
    // The class SinglyLinkedList provides an implementation of the List
    // interface using a singly linked list.  This differs from the Java
    // class LinkedList, which employs a doubly linked list and includes
    // additional methods beyond those required by the List interface.
    // Note: Included in this file is (at least) a "stub" method for each
    // of the required methods, as well as an implementation of the Node class.
    // This allows the file to compile without error messages and allows
    // you to implement the "actual" methods incrementally, testing as you go.
    // The List interface include some "optional" methods, some of which are
    // included here (see the List API for the meaning of this).
    // Some of the methods are preceded by comments indicating that you are
    // required to implement the method recursively.  Where there are no
    // such comments, you can provide either an iterative or a recursive
    // implementation, as you prefer.
    // There are some methods that you are asked not to implement at all.
    // Leave these as they are here: they are implemented here to just
    // throw an UnsupportedOperationException when they are called.
    // Hint: Read carefully the comments for the interface List in the
    // online documentation (Java API).  You can also take a look at the
    // implementation of the LinkedList class from the API. It uses a
    // doubly linked list and it is different in many places from what
    // you need to do here. However it may help you figure out how to do
    // some things. You shouldn't copy the code from there, rather you
    // should try to solve the problem by yourself and look into that code
    // only if you get stuck.
    import java.util.*;
    public class SinglyLinkedList implements List
      // an inner class: This is our node class, a singly linked node!
      private static class Node
        Object data;
        Node next;
        Node(Object o, Node n)
          data = o;
          next = n;
        Node(Object o)
          this(o, null);
        Node( )
          this(null,null);
      private Node head; // the "dummy" head reference
      private int size;  // the number of items on the list
      public SinglyLinkedList()
        head = new Node(); // dummy header node!
      public void add(int index, Object o)
      public boolean add(Object element)
      public boolean addAll(Collection c)
        return true;
      public boolean addAll(int index, Collection c)
        return true;
      public void clear()
      // write a recursive implementation here
      public boolean contains(Object o)
        return true;
      public boolean containsAll(Collection c)
        return true;
      public boolean equals(Object o)
        return true;
      // write a recursive implementation here
      public Object get(int index)
        return null;
      // NOT implemented: we don't cover hash codes
      // and hashing in this course
      public int hashCode()
        throw new UnsupportedOperationException();
      public int indexOf(Object o)
        return -1;
      public boolean isEmpty()
        return head.next == null;
      public Iterator iterator()
        return null;
      public int lastIndexOf(Object o)
        return -1;
      // Not implemented: The following two operations are not supported
      // since we are using a singly linked list, which does not allow
      // us to iterate through the elements back and forth easily
      // (going back is the problem)
      public ListIterator listIterator()
        throw new UnsupportedOperationException();
      public ListIterator listIterator(int index)
        throw new UnsupportedOperationException();
      // write a recursive implementation here
      public Object remove(int index)
        return null;
      public boolean remove(Object o)
        return true;
      public boolean removeAll(Collection c)
        return true;
      public boolean retainAll(Collection c)
        return true;
      // write a recursive implementation here
      public Object set(int index, Object element)
        return null;
      public int size()
        return size;
      // NOT implemented: to keep the homework reasonably simple
      public List subList(int fromIndex, int toIndex)
        throw new UnsupportedOperationException();
      public Object[] toArray()
        return null;
      public Object[] toArray(Object[] a)
        // you'll find this piece of code useful
        // it checks the exact type of the array passed as a parameter
        // in order to create a larger array of the same type.
        if (a.length < size)
          a = (Object[])java.lang.reflect.Array.
         newInstance(a.getClass().getComponentType(), size);
        // ... you need to write more code here!
        return a;
      private Node getNode(int index)
           Node p;
           if(index < 0 || index > size())
                throw new IndexOutOfBoundsException();
           if(index < size() / 2)
                p = head.next;
                for(int i = 0; i < index; i++)
                   p = p.next;
        return p;
      public static void main (String[] args){
           System.out.println("Singly Linked List");
           System.out.println();     
    }       

    Whoops, I realized that the add method returns a boolean. Unless you want to define a special contract, it should just return true or do something like this:
    public boolean add (Object o)
    {if (o == null) return false;
    // Check for dummy head node
    if (head.data == null)
    head = new Node(o, null);
    else
    // Traverse the list until we find the end
    Node next = head;
    while (next.next != null)
    next = next.next;
    next.next = new Node(o, null);
    }return true;

  • What does and mean in "List String "?

    Anyone familiair with this line:
    List<String> list = new ArrayList<String>(c)what does the "<String>" part precisely mean? I've been through the documentation, but I've not been able to find out what those "<" and ">" represent. Now I know that brackets ("[ ]") are used for arrays, but I doubt wether it's an principal equallity.
    So if someone knows its true meaning and/or has a nice URL for me to glance through some nice documentation...
    Thanks in advance!
    Tensos

    too late, it already did... seeing the code below (encountered in the general
    documentation), I'm afraid you're right...
    Object[] toArray();
    <T> T[] toArray(T[] a);An extra functionality is fine with me, but it is a
    pity that it doesn't make the code more easy readible
    (yet).It's easy to read once you get used to it, and I don't know how they would have been able to add generics with a syntax which is easier to understand, and yet is compact.
    Kaj

  • A suggestion : use "loop array list" instead of ArrayList / LinkedList

    ArrayList is good at:
    get / set by index : O(1)
    appending : O(log(n))
    remove last : O(1)
    and very bad at:
    add middle : O(n)
    remove from middle : O(n)
    LinkedList is good at:
    fast remove from middle, if your iteraror already goes there : O(1)
    convenient methods : addFirst, addLast, removeFirst, removeLast : O(1)
    and very bad at :
    get / set by index : O(n)
    here I want to make a suggestion : use "loop array list" instead of the ArrayList and LinkedList.
    a "loop array list" is based on array, just like ArrayList. But it has 2 member-variables : the start position, and the real size. the start position can be anywhere within array.length. an element of index "i" is stored in array[ start + i ], and when (start + i > array.length), loop to the beginning of the array; when (start + i < 0), loop to the end of the array.
    this "loop array list" has all the good sides:
    get / set by index : O(1)
    add first / last : O(log(n))
    remove first / last : O(log(n))
    add / remove from middle : O(n)
    (note : because we shrink the backup-array when the real size is too small, add / remove operation take O(log(n)) now.)
    the only problem is : add / remove from middle. let's take a look at it.
    1. the LinkedList does NOT really add/remove from middle in O(1), you has to locate the element, which is O(n).
    2. O(n) is acceptable, O(n^2) is not acceptable. try this : keep removing first element from an very big ArrayList ( size>10^6 ) until it's empty.
    the fact is, any list can perform batch-remove / batch-add operation in O(n) instead of O(n^2). it's easy : allocate a new list, iterate the original list, copy the element into the new list if condition is satisfied.
    so, instead of "remove from middle", what we need is a new methods : removeAllByCondition( Condition condition ), and now the batch-remove operation can be done in O(n)
    here is an implementation of mine. I've tested it on my computer( 512mem + 2G cpu, win2k + jdk1.5 ), it's amazing, just a little slower then ArrayList when add last, and a liitle slower then LinkedList when batch-remove. in all other cases, it's far more better then those 2 kinds of List.
    // source code : List2
    import java.util.AbstractList;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collection;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.List;
    import java.util.NoSuchElementException;
    import java.util.Set;
    public final class List2<T> extends AbstractList<T> {
    private static int initialArrayLength = 4;
    private T[] array;
    private int start;
    private int size;
    private void init( T[] newArray, int start_a, int size_a ) {
    array = newArray;
    start = start_a;
    size = size_a;
    @SuppressWarnings("unchecked")
    private void init() {
    init( (T[]) new Object[ initialArrayLength ], 0, 0 );
    public List2() {
         init();
    @SuppressWarnings("unchecked")
    public List2( Collection<? extends T> collection ) {
         init(
              collection.toArray( (T[]) new Object[ collection.size() * 11 / 10 + 1 ] ),
              0,
              collection.size()
    private List2( T[] array_a, int start_a, int size_a ) {
         init( array_a, start_a, size_a );
    @SuppressWarnings("unchecked")
    public static <TT> List2<TT> createV( TT... elements ) {
         TT[] array = (TT[]) new Object[ elements.length * 11 / 10 + 1 ];
         System.arraycopy( elements, 0, array, 0, elements.length );
         return new List2<TT>( array, 0, elements.length );
    public static List2<Double> create( double... elements ) {
         Double[] array = new Double[ elements.length * 11 / 10 + 1 ];
         for( int i=0; i < elements.length; i++ )
              array[i] = elements;
         return new List2<Double>( array, 0, elements.length );
    public static List2<Integer> create( int... elements ) {
         Integer[] array2 = new Integer[ elements.length * 11 / 10 + 1 ];
         for( int i=0; i < elements.length; i++ )
              array2[i] = elements[i];
         return new List2<Integer>( array2, 0, elements.length );
    public static List2<Character> create( char... elements ) {
         Character[] array2 = new Character[ elements.length * 11 / 10 + 1 ];
         for( int i=0; i < elements.length; i++ )
              array2[i] = elements[i];
         return new List2<Character>( array2, 0, elements.length );
    public static List2<Character> create( String s ) {
         return create( s.toCharArray() );
    public List2<T> clone() {
         return new List2<T>( this );
    // basic
    public int size() {
         return size;
    private int index( int index ) {
         int i = start + index;
         if( i >= array.length )
              i -= array.length;
         return i;
    public T get( int d ) {
         if( d < 0 || d >= size )
              throw new IndexOutOfBoundsException();
         if( size == 0 )
              throw new NoSuchElementException();
         return array[ index( d ) ];
    public T set( int index, T element ) {
         if( index < 0 || index >= size )
              throw new IndexOutOfBoundsException();
         int i = index( index );
         T oldElement = array[i];
         array[i] = element;
         return oldElement;
    @SuppressWarnings("unchecked")
    private void copyAndSetToNewArray( int newArrayLength ) {
         T[] newArray = (T[]) new Object[ newArrayLength ];
         for( int i=0; i<size; i++ )
              newArray[i] = array[ index( i ) ];
         init( newArray, 0, size );
    public void addFirst( T element ) {
         if( size == array.length )
              copyAndSetToNewArray( size * 3 / 2 + 1 );
         int i = index( array.length - 1 );
         array[ i ] = element;
         start = i;
         size++;
    public void addLast( T element ) {
         if( size == array.length )
              copyAndSetToNewArray( size * 3 / 2 + 1 );
         array[ index( size ) ] = element;
         size++;
    public T removeFirst() {
         if( size == 0 )
              throw new NoSuchElementException();
         T oldElement = array[ start ];
         array[ start ] = null;
         start = index( 1 );
         size--;
         if( array.length > size * 2 + 1 )
              copyAndSetToNewArray( size * 11 / 10 + 1 );
         return oldElement;
    public T removeLast() {
         if( size == 0 )
              throw new NoSuchElementException();
         int i = index( size - 1 );
         T oldElement = array[i];
         array[i] = null;
         size--;
         if( array.length > size * 2 + 1 )
              copyAndSetToNewArray( size * 11 / 10 + 1 );
         return oldElement;
    @SuppressWarnings("unchecked")
    public int removeAll( ListCondition<T> condition ) {
         T[] newArray = (T[]) new Object[ array.length ];
         int iNew = 0;
         for( int i=0; i < size; i++ ) {
              T element = get( i );
              if( ! condition.isConditionSatisfied( this, i, element ) )
                   newArray[ iNew++ ] = element;
         int oldSize = size;
         init( newArray, 0, iNew );
         if( array.length > size * 2 + 1 )
              copyAndSetToNewArray( size * 11 / 10 + 1 );
         return size - oldSize;
    // aux
    public boolean equals(Object obj) {
         if( obj == this )
         return true;
         if( obj instanceof List2 ) {
              List2 that = (List2) obj;
              if( this.size != that.size )
                   return false;
              for( int i=0; i < size; i++ )
                   if( ! Tools.equals( this.array[ this.index(i) ], that.array[ that.index(i) ] ) )
                        return false;
              return true;
         if( obj instanceof List ) {
              List that = (List) obj;
              if( this.size != that.size() )
                   return false;
              Iterator thatIter = that.iterator();
              for( int i=0; i < size; i++ )
                   if( ! Tools.equals( this.array[ this.index(i) ], thatIter.next() ) )
                        return false;
              return true;
         return true;
    public int hashCode() {
         int hashCode = 1;
         for( int i=0; i < size; i++ ) {
              T element = array[ index( i ) ];
         hashCode = 31*hashCode + ( element==null ? 0 : element.hashCode() );
         return hashCode;
    public boolean isEmpty() {
         return size == 0;
    public T getFirst() {
         return get( 0 );
    public T getLast() {
         return get( size() - 1 );
    public T getRandom() {
         return get( (int) (Math.random() * size) );
    public int indexOf( Object element ) {
         for( int i=0; i < size; i++ )
              if( Tools.equals( array[ index( i ) ], element ) )
                   return i;
         return -1;
    public int lastIndexOf( Object element ) {
         for( int i=size-1; i >= 0; i-- )
              if( Tools.equals( array[ index( i ) ], element ) )
                   return i;
         return -1;
    public boolean contains( Object element ) {
         return indexOf( element ) != -1;
    public boolean add( T element ) {
         addLast( element );
         return true;
    @Deprecated
    public void add( int index, T element ) {
         throw new UnsupportedOperationException();
    public T remove() {
         return removeFirst();
    @Deprecated
    public boolean remove( Object element ) {
         throw new UnsupportedOperationException( "use removeAll( Condition ) instead" );
    @Deprecated
    public T remove( int index ) {
         throw new UnsupportedOperationException( "use removeAll( Condition ) instead" );
    public void clear() {
         init();
    public Object[] toArray() {
         Object[] result = new Object[ size ];
         for( int i=0; i < size; i++ )
         result[i] = array[ index( i ) ];
         return result;
    @SuppressWarnings("unchecked")
    public <TT> TT[] toArray( TT[] a ) {
    if( a.length < size )
    a = (TT[]) java.lang.reflect.Array.newInstance( a.getClass().getComponentType(), size );
    for( int i=0; i < size; i++ )
    a[i] = (TT) array[ index( i ) ];
    if( a.length > size )
         a[size] = null;
    return a;
    @SuppressWarnings("unchecked")
    public void sort() {
         Object[] a = toArray();
         Arrays.sort( a );
         for( int i=0; i < size; i++ )
              array[ i ] = (T) a[ i ];
         start = 0;
    @SuppressWarnings("unchecked")
    public void sortDesc() {
         Object[] a = toArray();
         Arrays.sort( a );
         for( int i=0, j=size-1; i < size; i++, j-- )
              array[ i ] = (T) a[ j ];
         start = 0;
    @SuppressWarnings("unchecked")
    public void sort( Comparator<T> comparator ) {
         T[] a = (T[]) toArray();
         Arrays.sort( a, comparator );
         for( int i=0; i < size; i++ )
              array[ i ] = a[ i ];
         start = 0;
    @SuppressWarnings("unchecked")
    public void sortDesc( Comparator<T> comparator ) {
         T[] a = (T[]) toArray();
         Arrays.sort( a, comparator );
         for( int i=0, j=size-1; i < size; i++, j-- )
              array[ i ] = a[ j ];
         start = 0;
    public String toString( String delimiter ) {
         return toString( "", delimiter, "", size() );
    public String toString( String prefix, String delimiter, String suffix, int max ) {
         StringBuffer stringBuffer = new StringBuffer( prefix );
         int dest = Math.min( max, size );
         for( int i=0; i < dest; i++ ) {
              stringBuffer.append( get(i) );
              if( i < dest - 1 )
                   stringBuffer.append( delimiter );
         if( size > max )
              stringBuffer.append( "...(" ).append( size() - max ).append( " more)" );
         stringBuffer.append( suffix );
         return stringBuffer.toString();
    // batch operation
    public boolean containsAll( Collection<?> that ) {
         Set<Object> thisSet = new HashSet<Object>( this );
         for( Object element : that )
              if( ! thisSet.contains( element ) )
                   return false;
         return true;
    @SuppressWarnings("unchecked")
    public List2<T> subList( int fromIndex, int toIndex ) {
         if( fromIndex < 0 || toIndex > size || toIndex < fromIndex )
              throw new IndexOutOfBoundsException();
         int newSize = toIndex - fromIndex;
         T[] newArray = (T[]) new Object[ newSize * 11 / 10 + 1 ];
         for( int i=fromIndex, iNew=0; i < toIndex; i++, iNew++ )
              newArray[ iNew ] = array[ index( i ) ];
         return new List2<T>( newArray, 0, newSize );
    public void addV( T... that ) {
         for( T element : that )
              addLast( element );
    public boolean addAll( Collection<? extends T> that ) {
         for( T element : that )
              addLast( element );
         return ! that.isEmpty();
    @Deprecated
    public boolean addAll( int index, Collection<? extends T> c ) {
         throw new UnsupportedOperationException();
    public void removeRest( T element ) {
         int position = lastIndexOf( element );
         if( position == -1 )
              return;
         while( ! Tools.equals( element, removeLast() ) );
    public void removeAllEquals( final T element ) {
         removeAll( new ListCondition<T>() { public boolean isConditionSatisfied(List2 list, int index, T currentElement) {
              return currentElement.equals( element );
    public void removeAllBetween( final T from, final T to ) {
         removeAll( new ListCondition<T>() {
              @SuppressWarnings("unchecked")
              public boolean isConditionSatisfied(List2 list, int index, T element) {
                   if( from != null && ((Comparable) from).compareTo( element ) > 0 )
                        return false;
                   if( to != null && ((Comparable) to).compareTo( element ) <= 0 )
                        return false;
                   return true;
    public boolean retainAll( Collection<?> that ) {
         final Set<Object> thatSet = new HashSet<Object>( that );
         int removeCount = removeAll( new ListCondition<T>() { public boolean isConditionSatisfied(List2 list, int index, T element) {
              return ! thatSet.contains( element );
         return removeCount > 0;
    public boolean removeAll( Collection<?> that ) {
         final Set<Object> thatSet = new HashSet<Object>( that );
         int removeCount = removeAll( new ListCondition<T>() { public boolean isConditionSatisfied(List2 list, int index, T element) {
              return thatSet.contains( element );
         return removeCount > 0;
    // unit test
    private static int maxTestCount = 1000 * 1000;
    public static void unitTest() throws Exception {
         // thest thoese methods for one time
         Tools.ensureEquals( new List2(), new ArrayList() );
         Tools.ensureNotEquals( List2.create( "abcde" ), new ArrayList() );
         Tools.ensureNotEquals( List2.create( "abcde" ), List2.create( "abcdef" ) );
         final List<Double> list1 = new ArrayList<Double>();
         final List2<Double> list2 = new List2<Double>();
         Runnable[] tasks = new Runnable[] {
              // test those methods that do NOT change the list
              new Runnable() { public void run() {
                   Tools.ensureEquals( new List2<Double>( list1 ), list1 );
                   Tools.ensureEquals( List2.createV( list1.toArray() ), list1 );
                   Tools.ensureEquals( List2.createV( list1.toArray( new Double[0] ) ), list1 );
                   double[] doubles = new double[ list1.size() ];
                   int i = 0;
                   for( double d : list1 )
                        doubles[i++] = d;
                   Tools.ensureEquals( List2.create( doubles ), list1 );
                   Tools.ensure( list1.isEmpty() == list2.isEmpty() );
                   Arrays.equals( list1.toArray(), list2.toArray() );
                   Tools.ensureEquals( list1, list2.clone() );
                   Double notExistElement = -2.0;
                   Tools.ensure( list1.indexOf( notExistElement ) == -1 );
                   Tools.ensure( list1.lastIndexOf( notExistElement ) == -1 );
                   Tools.ensure( list1.contains( notExistElement ) == false );
                   Tools.ensureEquals( list1.toString(), list2.toString() );
                   Tools.ensureEquals( list1.toString(), list2.toString() );
                   Tools.ensureEquals( list1.hashCode(), list2.hashCode() );
                   if( list1.isEmpty() )
                        return;
                   Tools.ensure( list1.get(0).equals( list2.getFirst() ) );
                   Tools.ensure( list1.get(list1.size()-1).equals( list2.getLast() ) );
                   Double existRandomElement = list2.getRandom();
                   Tools.ensure( list1.contains( existRandomElement ) );
                   Tools.ensure( list2.contains( existRandomElement ) );
                   Tools.ensure( list1.indexOf( existRandomElement ) == list2.indexOf( existRandomElement ) );
                   Tools.ensure( list1.indexOf( existRandomElement ) == list2.indexOf( existRandomElement ) );
                   int from = (int) (Math.random() * list1.size());
                   int to = (int) (Math.random() * (list1.size()+1));
                   if( from > to ) {
                        int t = from;
                        from = to;
                        to = t;
                   Tools.ensureEquals( list1.subList( from, to ), list2.subList( from, to ) );
              // test those methods that change the list
              new Runnable() { public void run() {
                   if( list1.isEmpty() )
                        return;
                   int i = (int) (Math.random() * list1.size());
                   double d = Math.random();
                   list1.set( i, d );
                   list2.set( i, d );
              new Runnable() { public void run() {
                   if( list1.isEmpty() )
                        return;
                   int i = (int) (Math.random() * list1.size());
                   Tools.ensure( list1.get( i ).equals( list2.get( i ) ) );
              new Runnable() { public void run() {
                   double d = Math.random();
                   list1.add( 0, d );
                   list2.addFirst( d );
              new Runnable() { public void run() {
                   double d = Math.random();
                   list1.add( d );
                   list2.addLast( d );
              new Runnable() { public void run() {
                   double d = Math.random();
                   list1.add( d );
                   list2.addLast( d );
              new Runnable() { public void run() {
                   if( list1.isEmpty() )
                        return;
                   Tools.ensure( list1.remove( 0 ).equals( list2.removeFirst() ) );
              new Runnable() { public void run() {
                   if( list1.isEmpty() )
                        return;
                   Tools.ensure( list1.remove( list1.size() - 1 ).equals( list2.removeLast() ) );
              new Runnable() { public void run() {
                   if( list1.isEmpty() )
                        return;
                   int i = 0;
                   for( Iterator<Double> iter=list1.iterator(); iter.hasNext(); i++ ) {
                        iter.next();
                        if( i % 3 == 0 )
                             iter.remove();
                   list2.removeAll( new ListCondition<Double>() { public boolean isConditionSatisfied(List2 list, int index, Double element) {
                        return index % 3 == 0;
              new Runnable() { public void run() {
                   double d = Math.random();
                   list1.add( d );
                   list2.add( d );
              new Runnable() { public void run() {
                   if( list1.isEmpty() )
                        return;
                   Tools.ensure( list1.remove(0).equals( list2.remove() ) );
              new Runnable() { public void run() {
                   if( list1.isEmpty() )
                        return;
                   int r = (int) (Math.random() * list1.size());
                   Double element = list1.get( r );
                   int index = list1.lastIndexOf( element );
                   for( int i=list1.size()-1; i>=index; i-- )
                        list1.remove( i );
                   list2.removeRest( element );
              new Runnable() { public void run() {
                   list2.removeRest( Math.random() - 2 );
              new Runnable() { public void run() {
                   list1.clear();
                   list2.clear();
              new Runnable() { public void run() {
                   Collections.sort( list1 );
                   list2.sort();
              new Runnable() { public void run() {
                   Collections.sort( list1 );
                   Collections.reverse( list1 );
                   list2.sortDesc();
              new Runnable() { public void run() {
                   Comparator<Double> comparator = new Comparator<Double>() { public int compare(Double o1, Double o2) {
                        return o1.toString().substring(2).compareTo( o2.toString().substring(2) );
                   Collections.sort( list1, comparator );
                   list2.sort( comparator );
              new Runnable() { public void run() {
                   Comparator<Double> comparator = new Comparator<Double>() { public int compare(Double o1, Double o2) {
                        return o1.toString().substring(2).compareTo( o2.toString().substring(2) );
                   Collections.sort( list1, comparator );
                   Collections.reverse( list1 );
                   list2.sortDesc( comparator );
              new Runnable() { public void run() {
                   Double notExistElement = -2.0;
                   list2.removeAllEquals( notExistElement );
                   Tools.ensureEquals( list1, list2 );
                   list2.removeAllBetween( 0.5, 0.6 );
                   for( Iterator<Double> iter=list1.iterator(); iter.hasNext(); ) {
                        double d = iter.next();
                        if( d >= 0.5 && d < 0.6 )
                             iter.remove();
                   Tools.ensureEquals( list1, list2 );
         System.out.print( "test List2 " );
         for( int i=0; i < maxTestCount; i++ ) {
              tasks[ (int) (Math.random() * tasks.length) ].run();
              Tools.ensureEquals( list1, list2 );
              if( i % (maxTestCount/10) == 0 )
                   System.out.print( "." );
         System.out.println( " ok" );
    // source code : ListCondition
    public interface ListCondition<T> {
    boolean isConditionSatisfied( List2 list, int index, T element );

    Hi,
    I have the following statement:
    private List list = new ArrayList();
    why not use private ArrayList list = new
    ArrayList()?
    I know ArrayList implements List, so list has a wide
    scope, right? What's the benefit?
    Thanks,
    JieBy using the interface you are not tied to a specific implementation.
    Later, you may determine that using a LinkedList is more efficient to your specific code and then all you need to do is change the statement to:
    private List list = new LinkedList();As long as you are not casting the list reference to ArrayList (or something along those lines) you would not need to change anything else.

  • HELP me with the source code

    In this assignment you are asked to create a Java class that simulates the Java Vector class. You are also asked to create two Exception classes to allow the program to continue if errors occur. These are �MyVectNoDataException� and �MyVectIndexOutOfBoundsException�.
    1.     Write a Java class called �myVect� which will operate in the same way as the Java Vector class. In particular it should have
    a.     The following data members
    i.     An Object array
    ii.     An integer �size� that determines the size of the array
    iii.     An integer �increment� that defines the number of additional elements that will be added when the Array is to be resized.
    b.     The following methods
    i.     Constructor 1      myVect()that creates a new myVect object with an internal array size of 10 and an increment of 3.
    ii.     Constructor 2           myVect(int s)
    that creates a new myVect object with an internal array size of s and an increment of 3.
    iii.     Constructor 3           myVect(int s, int i)
    that creates a new myVect object with an internal array size of s and an increment of i.
    iv.     A method          void resize()
    that increases the size of the internal array by the number of elements in the �increment� variable.
    v.     A method      void addElement(Object o)
    that inserts an Object at the next available position in the internal array. If there are less than 3 vacant elements left in the array then the resize() method should be run automatically.
    vi.     A method      void deleteElement()
    that deletes the Object at the last occupied position in the internal array. If no element contains an Object then a MyVectNoDataException should be thrown and the program should continue.
    vii.     A method void insertElement(Object o,int p)
    that inserts an Object at position p in the internal array. The Objects at position p and below should each be moved down by one position before the insertion.
    If the index p is outside the bounds of the internal array then a MyVectIndexOutOfBoundsException should be thrown and the program should continue.
    viii.     A method void deleteElementAt(int p)
    that deletes the Object at position p in the internal array. The Objects below position p should each be moved up by one position after the deletion. If the index p is outside the bounds of the internal array then a MyVectIndexOutOfBoundsException should be thrown and the program should continue.
    If the position p is valid but does not contain an Object then a MyVectNoDataException should be thrown and the program should continue.
    ix.     A method      Object getElement()
    that returns the Object at the last occupied position in the internal array.
    x.     A method      Object getElementAt(int p)
    that returns the Object at position p in the internal array. If the index p is outside the bounds of the internal array then a MyVectIndexOutOfBoundsException should be thrown and the program should continue. If the position p is valid but does not contain an Object then a MyVectNoDataException should be thrown and the program should continue.
    xi.     A toString() method that produces a formatted String representing the myVect object and its data. It should also include the size and increment values.
    c.     Write a Java program called Assign3.java that creates a myVect object then
    i.     Store 6 objects of the following types
    1.     String
    2.     Date
    3.     Integer
    4.     String
    5.     StringTokenizer
    6.     Date
    ii.     Print the myVect object.
    iii.     Add 2 more objects
    1.     StringBuffer
    2.     Double
    iv.     Print the myVect object
    v.     Delete the Object at position 2
    vi.     Delete the Object at position 15
    vii.     Display the Object at position 10
    viii.     Display the length of the second String.
    ix.     Print the myVect object
    d.     Include Javadoc comments in the myVect class code then produce Java documentation using Javadoc.

    * @(#)MyOwnVectorReallyItIs.java     1.89 03/01/23
    * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
    * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
    package java.util;
    * The <code>MyOwnVectorReallyItIs</code> class implements a growable array of
    * objects. Like an array, it contains components that can be
    * accessed using an integer index. However, the size of a
    * <code>MyOwnVectorReallyItIs</code> can grow or shrink as needed to accommodate
    * adding and removing items after the <code>MyOwnVectorReallyItIs</code> has been created.<p>
    * Each MyOwnVectorReallyItIs tries to optimize storage management by maintaining a
    * <code>capacity</code> and a <code>capacityIncrement</code>. The
    * <code>capacity</code> is always at least as large as the MyOwnVectorReallyItIs
    * size; it is usually larger because as components are added to the
    * MyOwnVectorReallyItIs, the MyOwnVectorReallyItIs's storage increases in chunks the size of
    * <code>capacityIncrement</code>. An application can increase the
    * capacity of a MyOwnVectorReallyItIs before inserting a large number of
    * components; this reduces the amount of incremental reallocation. <p>
    * As of the Java 2 platform v1.2, this class has been retrofitted to
    * implement List, so that it becomes a part of Java's collection framework.
    * Unlike the new collection implementations, MyOwnVectorReallyItIs is synchronized.<p>
    * The Iterators returned by MyOwnVectorReallyItIs's iterator and listIterator
    * methods are <em>fail-fast</em>: if the MyOwnVectorReallyItIs is structurally modified
    * at any time after the Iterator is created, in any way except through the
    * Iterator's own remove or add methods, the Iterator will throw a
    * ConcurrentModificationException.  Thus, in the face of concurrent
    * modification, the Iterator fails quickly and cleanly, rather than risking
    * arbitrary, non-deterministic behavior at an undetermined time in the future.
    * The Enumerations returned by MyOwnVectorReallyItIs's elements method are <em>not</em>
    * fail-fast.
    * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
    * as it is, generally speaking, impossible to make any hard guarantees in the
    * presence of unsynchronized concurrent modification.  Fail-fast iterators
    * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
    * Therefore, it would be wrong to write a program that depended on this
    * exception for its correctness:  <i>the fail-fast behavior of iterators
    * should be used only to detect bugs.</i><p>
    * This class is a member of the
    * <a href="{@docRoot}/../guide/collections/index.html">
    * Java Collections Framework</a>.
    * @author  Lee Boynton
    * @author  Jonathan Payne
    * @version 1.89, 01/23/03
    * @see Collection
    * @see List
    * @see ArrayList
    * @see LinkedList
    * @since   JDK1.0
    public class MyOwnVectorReallyItIs extends AbstractList
            implements List, RandomAccess, Cloneable, java.io.Serializable
         * The array buffer into which the components of the MyOwnVectorReallyItIs are
         * stored. The capacity of the MyOwnVectorReallyItIs is the length of this array buffer,
         * and is at least large enough to contain all the MyOwnVectorReallyItIs's elements.<p>
         * Any array elements following the last element in the MyOwnVectorReallyItIs are null.
         * @serial
        protected Object elementData[];
         * The number of valid components in this <tt>MyOwnVectorReallyItIs</tt> object.
         * Components <tt>elementData[0]</tt> through
         * <tt>elementData[elementCount-1]</tt> are the actual items.
         * @serial
        protected int elementCount;
         * The amount by which the capacity of the MyOwnVectorReallyItIs is automatically
         * incremented when its size becomes greater than its capacity.  If
         * the capacity increment is less than or equal to zero, the capacity
         * of the MyOwnVectorReallyItIs is doubled each time it needs to grow.
         * @serial
        protected int capacityIncrement;
        /** use serialVersionUID from JDK 1.0.2 for interoperability */
        private static final long serialVersionUID = -2767605614048989439L;
         * Constructs an empty MyOwnVectorReallyItIs with the specified initial capacity and
         * capacity increment.
         * @param   initialCapacity     the initial capacity of the MyOwnVectorReallyItIs.
         * @param   capacityIncrement   the amount by which the capacity is
         *                              increased when the MyOwnVectorReallyItIs overflows.
         * @exception IllegalArgumentException if the specified initial capacity
         *               is negative
        public MyOwnVectorReallyItIs(int initialCapacity, int capacityIncrement) {
         super();
            if (initialCapacity < 0)
                throw new IllegalArgumentException("Illegal Capacity: "+
                                                   initialCapacity);
         this.elementData = new Object[initialCapacity];
         this.capacityIncrement = capacityIncrement;
         * Constructs an empty MyOwnVectorReallyItIs with the specified initial capacity and
         * with its capacity increment equal to zero.
         * @param   initialCapacity   the initial capacity of the MyOwnVectorReallyItIs.
         * @exception IllegalArgumentException if the specified initial capacity
         *               is negative
        public MyOwnVectorReallyItIs(int initialCapacity) {
         this(initialCapacity, 0);
         * Constructs an empty MyOwnVectorReallyItIs so that its internal data array
         * has size <tt>10</tt> and its standard capacity increment is
         * zero.
        public MyOwnVectorReallyItIs() {
         this(10);
         * Constructs a MyOwnVectorReallyItIs containing the elements of the specified
         * collection, in the order they are returned by the collection's
         * iterator.
         * @param c the collection whose elements are to be placed into this
         *       MyOwnVectorReallyItIs.
         * @throws NullPointerException if the specified collection is null.
         * @since   1.2
        public MyOwnVectorReallyItIs(Collection c) {
            elementCount = c.size();
            // 10% for growth
            elementData = new Object[
                          (int)Math.min((elementCount*110L)/100,Integer.MAX_VALUE)];
            c.toArray(elementData);
         * Copies the components of this MyOwnVectorReallyItIs into the specified array. The
         * item at index <tt>k</tt> in this MyOwnVectorReallyItIs is copied into component
         * <tt>k</tt> of <tt>anArray</tt>. The array must be big enough to hold
         * all the objects in this MyOwnVectorReallyItIs, else an
         * <tt>IndexOutOfBoundsException</tt> is thrown.
         * @param   anArray   the array into which the components get copied.
         * @throws  NullPointerException if the given array is null.
        public synchronized void copyInto(Object anArray[]) {
         System.arraycopy(elementData, 0, anArray, 0, elementCount);
         * Trims the capacity of this MyOwnVectorReallyItIs to be the MyOwnVectorReallyItIs's current
         * size. If the capacity of this MyOwnVectorReallyItIs is larger than its current
         * size, then the capacity is changed to equal the size by replacing
         * its internal data array, kept in the field <tt>elementData</tt>,
         * with a smaller one. An application can use this operation to
         * minimize the storage of a MyOwnVectorReallyItIs.
        public synchronized void trimToSize() {
         modCount++;
         int oldCapacity = elementData.length;
         if (elementCount < oldCapacity) {
             Object oldData[] = elementData;
             elementData = new Object[elementCount];
             System.arraycopy(oldData, 0, elementData, 0, elementCount);
         * Increases the capacity of this MyOwnVectorReallyItIs, if necessary, to ensure
         * that it can hold at least the number of components specified by
         * the minimum capacity argument.
         * <p>If the current capacity of this MyOwnVectorReallyItIs is less than
         * <tt>minCapacity</tt>, then its capacity is increased by replacing its
         * internal data array, kept in the field <tt>elementData</tt>, with a
         * larger one.  The size of the new data array will be the old size plus
         * <tt>capacityIncrement</tt>, unless the value of
         * <tt>capacityIncrement</tt> is less than or equal to zero, in which case
         * the new capacity will be twice the old capacity; but if this new size
         * is still smaller than <tt>minCapacity</tt>, then the new capacity will
         * be <tt>minCapacity</tt>.
         * @param minCapacity the desired minimum capacity.
        public synchronized void ensureCapacity(int minCapacity) {
         modCount++;
         ensureCapacityHelper(minCapacity);
         * This implements the unsynchronized semantics of ensureCapacity.
         * Synchronized methods in this class can internally call this
         * method for ensuring capacity without incurring the cost of an
         * extra synchronization.
         * @see java.util.MyOwnVectorReallyItIs#ensureCapacity(int)
        private void ensureCapacityHelper(int minCapacity) {
         int oldCapacity = elementData.length;
         if (minCapacity > oldCapacity) {
             Object oldData[] = elementData;
             int newCapacity = (capacityIncrement > 0) ?
              (oldCapacity + capacityIncrement) : (oldCapacity * 2);
                 if (newCapacity < minCapacity) {
              newCapacity = minCapacity;
             elementData = new Object[newCapacity];
             System.arraycopy(oldData, 0, elementData, 0, elementCount);
         * Sets the size of this MyOwnVectorReallyItIs. If the new size is greater than the
         * current size, new <code>null</code> items are added to the end of
         * the MyOwnVectorReallyItIs. If the new size is less than the current size, all
         * components at index <code>newSize</code> and greater are discarded.
         * @param   newSize   the new size of this MyOwnVectorReallyItIs.
         * @throws  ArrayIndexOutOfBoundsException if new size is negative.
        public synchronized void setSize(int newSize) {
         modCount++;
         if (newSize > elementCount) {
             ensureCapacityHelper(newSize);
         } else {
             for (int i = newSize ; i < elementCount ; i++) {
              elementData[i] = null;
         elementCount = newSize;
         * Returns the current capacity of this MyOwnVectorReallyItIs.
         * @return  the current capacity (the length of its internal
         *          data array, kept in the field <tt>elementData</tt>
         *          of this MyOwnVectorReallyItIs).
        public synchronized int capacity() {
         return elementData.length;
         * Returns the number of components in this MyOwnVectorReallyItIs.
         * @return  the number of components in this MyOwnVectorReallyItIs.
        public synchronized int size() {
         return elementCount;
         * Tests if this MyOwnVectorReallyItIs has no components.
         * @return  <code>true</code> if and only if this MyOwnVectorReallyItIs has
         *          no components, that is, its size is zero;
         *          <code>false</code> otherwise.
        public synchronized boolean isEmpty() {
         return elementCount == 0;
         * Returns an enumeration of the components of this MyOwnVectorReallyItIs. The
         * returned <tt>Enumeration</tt> object will generate all items in
         * this MyOwnVectorReallyItIs. The first item generated is the item at index <tt>0</tt>,
         * then the item at index <tt>1</tt>, and so on.
         * @return  an enumeration of the components of this MyOwnVectorReallyItIs.
         * @see     Enumeration
         * @see     Iterator
        public Enumeration elements() {
         return new Enumeration() {
             int count = 0;
             public boolean hasMoreElements() {
              return count < elementCount;
             public Object nextElement() {
              synchronized (MyOwnVectorReallyItIs.this) {
                  if (count < elementCount) {
                   return elementData[count++];
              throw new NoSuchElementException("MyOwnVectorReallyItIs Enumeration");
         * Tests if the specified object is a component in this MyOwnVectorReallyItIs.
         * @param   elem   an object.
         * @return  <code>true</code> if and only if the specified object
         * is the same as a component in this MyOwnVectorReallyItIs, as determined by the
         * <tt>equals</tt> method; <code>false</code> otherwise.
        public boolean contains(Object elem) {
         return indexOf(elem, 0) >= 0;
         * Searches for the first occurence of the given argument, testing
         * for equality using the <code>equals</code> method.
         * @param   elem   an object.
         * @return  the index of the first occurrence of the argument in this
         *          MyOwnVectorReallyItIs, that is, the smallest value <tt>k</tt> such that
         *          <tt>elem.equals(elementData[k])</tt> is <tt>true</tt>;
         *          returns <code>-1</code> if the object is not found.
         * @see     Object#equals(Object)
        public int indexOf(Object elem) {
         return indexOf(elem, 0);
         * Searches for the first occurence of the given argument, beginning
         * the search at <code>index</code>, and testing for equality using
         * the <code>equals</code> method.
         * @param   elem    an object.
         * @param   index   the non-negative index to start searching from.
         * @return  the index of the first occurrence of the object argument in
         *          this MyOwnVectorReallyItIs at position <code>index</code> or later in the
         *          MyOwnVectorReallyItIs, that is, the smallest value <tt>k</tt> such that
         *          <tt>elem.equals(elementData[k]) && (k >= index)</tt> is
         *          <tt>true</tt>; returns <code>-1</code> if the object is not
         *          found. (Returns <code>-1</code> if <tt>index</tt> >= the
         *          current size of this <tt>MyOwnVectorReallyItIs</tt>.)
         * @exception  IndexOutOfBoundsException  if <tt>index</tt> is negative.
         * @see     Object#equals(Object)
        public synchronized int indexOf(Object elem, int index) {
         if (elem == null) {
             for (int i = index ; i < elementCount ; i++)
              if (elementData==null)
              return i;
         } else {
         for (int i = index ; i < elementCount ; i++)
              if (elem.equals(elementData[i]))
              return i;
         return -1;
    * Returns the index of the last occurrence of the specified object in
    * this MyOwnVectorReallyItIs.
    * @param elem the desired component.
    * @return the index of the last occurrence of the specified object in
    * this MyOwnVectorReallyItIs, that is, the largest value <tt>k</tt> such that
    * <tt>elem.equals(elementData[k])</tt> is <tt>true</tt>;
    * returns <code>-1</code> if the object is not found.
    public synchronized int lastIndexOf(Object elem) {
         return lastIndexOf(elem, elementCount-1);
    * Searches backwards for the specified object, starting from the
    * specified index, and returns an index to it.
    * @param elem the desired component.
    * @param index the index to start searching from.
    * @return the index of the last occurrence of the specified object in this
    * MyOwnVectorReallyItIs at position less than or equal to <code>index</code> in
    * the MyOwnVectorReallyItIs, that is, the largest value <tt>k</tt> such that
    * <tt>elem.equals(elementData[k]) && (k <= index)</tt> is
    * <tt>true</tt>; <code>-1</code> if the object is not found.
    * (Returns <code>-1</code> if <tt>index</tt> is negative.)
    * @exception IndexOutOfBoundsException if <tt>index</tt> is greater
    * than or equal to the current size of this MyOwnVectorReallyItIs.
    public synchronized int lastIndexOf(Object elem, int index) {
    if (index >= elementCount)
    throw new IndexOutOfBoundsException(index + " >= "+ elementCount);
         if (elem == null) {
         for (int i = index; i >= 0; i--)
              if (elementData[i]==null)
              return i;
         } else {
         for (int i = index; i >= 0; i--)
              if (elem.equals(elementData[i]))
              return i;
         return -1;
    * Returns the component at the specified index.<p>
    * This method is identical in functionality to the get method
    * (which is part of the List interface).
    * @param index an index into this MyOwnVectorReallyItIs.
    * @return the component at the specified index.
    * @exception ArrayIndexOutOfBoundsException if the <tt>index</tt>
    * is negative or not less than the current size of this
    * <tt>MyOwnVectorReallyItIs</tt> object.
    * given.
    * @see     #get(int)
    * @see     List
    public synchronized Object elementAt(int index) {
         if (index >= elementCount) {
         throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
    return elementData[index];
    * Returns the first component (the item at index <tt>0</tt>) of
    * this MyOwnVectorReallyItIs.
    * @return the first component of this MyOwnVectorReallyItIs.
    * @exception NoSuchElementException if this MyOwnVectorReallyItIs has no components.
    public synchronized Object firstElement() {
         if (elementCount == 0) {
         throw new NoSuchElementException();
         return elementData[0];
    * Returns the last component of the MyOwnVectorReallyItIs.
    * @return the last component of the MyOwnVectorReallyItIs, i.e., the component at index
    * <code>size() - 1</code>.
    * @exception NoSuchElementException if this MyOwnVectorReallyItIs is empty.
    public synchronized Object lastElement() {
         if (elementCount == 0) {
         throw new NoSuchElementException();
         return elementData[elementCount - 1];
    * Sets the component at the specified <code>index</code> of this
    * MyOwnVectorReallyItIs to be the specified object. The previous component at that
    * position is discarded.<p>
    * The index must be a value greater than or equal to <code>0</code>
    * and less than the current size of the MyOwnVectorReallyItIs. <p>
    * This method is identical in functionality to the set method
    * (which is part of the List interface). Note that the set method reverses
    * the order of the parameters, to more closely match array usage. Note
    * also that the set method returns the old value that was stored at the
    * specified position.
    * @param obj what the component is to be set to.
    * @param index the specified index.
    * @exception ArrayIndexOutOfBoundsException if the index was invalid.
    * @see #size()
    * @see List
    * @see     #set(int, java.lang.Object)
    public synchronized void setElementAt(Object obj, int index) {
         if (index >= elementCount) {
         throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                  elementCount);
         elementData[index] = obj;
    * Deletes the component at the specified index. Each component in
    * this MyOwnVectorReallyItIs with an index greater or equal to the specified
    * <code>index</code> is shifted downward to have an index one
    * smaller than the value it had previously. The size of this MyOwnVectorReallyItIs
    * is decreased by <tt>1</tt>.<p>
    * The index must be a value greater than or equal to <code>0</code>
    * and less than the current size of the MyOwnVectorReallyItIs. <p>
    * This method is identical in functionality to the remove method
    * (which is part of the List interface). Note that the remove method
    * returns the old value that was stored at the specified position.
    * @param index the index of the object to remove.
    * @exception ArrayIndexOutOfBoundsException if the index was invalid.
    * @see #size()
    * @see     #remove(int)
    * @see     List
    public synchronized void removeElementAt(int index) {
         modCount++;
         if (index >= elementCount) {
         throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                  elementCount);
         else if (index < 0) {
         throw new ArrayIndexOutOfBoundsException(index);
         int j = elementCount - index - 1;
         if (j > 0) {
         System.arraycopy(elementData, index + 1, elementData, index, j);
         elementCount--;
         elementData[elementCount] = null; /* to let gc do its work */
    * Inserts the specified object as a component in this MyOwnVectorReallyItIs at the
    * specified <code>index</code>. Each component in this MyOwnVectorReallyItIs with
    * an index greater or equal to the specified <code>index</code> is
    * shifted upward to have an index one greater than the value it had
    * previously. <p>
    * The index must be a value greater than or equal to <code>0</code>
    * and less than or equal to the current size of the MyOwnVectorReallyItIs. (If the
    * index is equal to the current size of the MyOwnVectorReallyItIs, the new element
    * is appended to the MyOwnVectorReallyItIs.)<p>
    * This method is identical in functionality to the add(Object, int) method
    * (which is part of the List interface). Note that the add method reverses
    * the order of the parameters, to more closely match array usage.
    * @param obj the component to insert.
    * @param index where to insert the new component.
    * @exception ArrayIndexOutOfBoundsException if the index was invalid.
    * @see #size()
    * @see     #add(int, Object)
    * @see     List
    public synchronized void insertElementAt(Object obj, int index) {
         modCount++;
         if (index > elementCount) {
         throw new ArrayIndexOutOfBoundsException(index
                                  + " > " + elementCount);
         ensureCapacityHelper(elementCount + 1);
         System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
         elementData[index] = obj;
         elementCount++;
    * Adds the specified component to the end of this MyOwnVectorReallyItIs,
    * increasing its size by one. The capacity of this MyOwnVectorReallyItIs is
    * increased if its size becomes greater than its capacity. <p>
    * This method is identical in functionality to the add(Object) method
    * (which is part of the List interface).
    * @param obj the component to be added.
    * @see     #add(Object)
    * @see     List
    public synchronized void addElement(Object obj) {
         modCount++;
         ensureCapacityHelper(elementCount + 1);
         elementData[elementCount++] = obj;
    * Removes the first (lowest-indexed) occurrence of the argument
    * from this MyOwnVectorReallyItIs. If the object is found in this MyOwnVectorReallyItIs, each
    * component in the MyOwnVectorReallyItIs with an index greater or equal to the
    * object's index is shifted downward to have an index one smaller
    * than the value it had previously.<p>
    * This method is identical in functionality to the remove(Object)
    * method (which is part of the List interface).
    * @param obj the component to be removed.
    * @return <code>true</code> if the argument was a component of this
    * MyOwnVectorReallyItIs; <code>false</code> otherwise.
    * @see     List#remove(Object)
    * @see     List
    public synchronized boolean removeElement(Object obj) {
         modCount++;
         int i = indexOf(obj);
         if (i >= 0) {
         removeElementAt(i);
         return true;
         return false;
    * Removes all components from this MyOwnVectorReallyItIs and sets its size to zero.<p>
    * This method is identical in functionality to the clear method
    * (which is part of the List interface).
    * @see     #clear
    * @see     List
    public synchronized void removeAllElements() {
    modCount++;
         // Let gc do its work
         for (int i = 0; i < elementCount; i++)
         elementData[i] = null;
         elementCount = 0;
    * Returns a clone of this MyOwnVectorReallyItIs. The copy will contain a
    * reference to a clone of the internal data array, not a reference
    * to the original internal data array of this <tt>MyOwnVectorReallyItIs</tt> object.
    * @return a clone of this MyOwnVectorReallyItIs.
    public synchronized Object clone() {
         try {
         MyOwnVectorReallyItIs v = (MyOwnVectorReallyItIs)super.clone();
         v.elementData = new Object[elementCount];
         System.arraycopy(elementData, 0, v.elementData, 0, elementCount);
         v.modCount = 0;
         return v;
         } catch (CloneNotSupportedException e) {
         // this shouldn't happen, since we are Cloneable
         throw new InternalError();
    * Returns an array containing all of the elements in this MyOwnVectorReallyItIs
    * in the correct order.
    * @since 1.2
    public synchronized Object[] toArray() {
         Object[] result = new Object[elementCount];
         System.arraycopy(elementData, 0, result, 0, elementCount);
         return result;
    * Returns an array containing all of the elements in this MyOwnVectorReallyItIs in the
    * correct order; the runtime type of the returned array is that of the
    * specified array. If the MyOwnVectorReallyItIs fits in the specified array, it is
    * returned therein. Otherwise, a new array is allocated with the runtime
    * type of the specified array and the size of this MyOwnVectorReallyItIs.<p>
    * If the MyOwnVectorReallyItIs fits in the specified array with room to spare
    * (i.e., the array has more elements than the MyOwnVectorReallyItIs),
    * the element in the array immediately following the end of the
    * MyOwnVectorReallyItIs is set to null. This is useful in determining the length
    * of the MyOwnVectorReallyItIs <em>only</em> if the caller knows that the MyOwnVectorReallyItIs
    * does not contain any null elements.
    * @param a the array into which the elements of the MyOwnVectorReallyItIs are to
    *          be stored, if it is big enough; otherwise, a new array of the
    *           same runtime type is allocated for this purpose.
    * @return an array containing the elements of the MyOwnVectorReallyItIs.
    * @exception ArrayStoreException the runtime type of a is not a supertype
    * of the runtime type of every element in this MyOwnVectorReallyItIs.
    * @throws NullPointerException if the given array is null.
    * @since 1.2
    public synchronized Object[] toArray(Object a[]) {
    if (a.length < elementCount)
    a = (Object[])java.lang.reflect.Array.newInstance(
    a.getClass().getComponentType(), elementCount);
         System.arraycopy(elementData, 0, a, 0, elementCount);
    if (a.length > elementCount)
    a[elementCount] = null;
    return a;
    // Positional Access Operations
    * Returns the element at the specified position in this MyOwnVectorReallyItIs.
    * @param index index of element to return.
    * @return object at the specified index
    * @exception ArrayIndexOutOfBoundsException index is out of range (index
    *           < 0 || index >= size()).
    * @since 1.2
    public synchronized Object get(int index) {
         if (index >= elementCount)
         throw new ArrayIndexOutOfBoundsException(index);
         return elementData[index];
    * Replaces the element at the specified position in this MyOwnVectorReallyItIs with the
    * specified element.
    * @param index index of element to replace.
    * @param element element to be stored at the specified position.
    * @return the element previously at the specified position.
    * @exception ArrayIndexOutOfBoundsException index out of range
    *          (index < 0 || index >= size()).
    * @since 1.2
    public synchronized Object set(int index, Object element) {
         if (index >= elementCount)
         throw new ArrayIndexOutOfBoundsException(index);
         Object oldValue = elementData[index];
         elementData[index] = element;
         return oldValue;
    * Appends the specified element to the end of this MyOwnVectorReallyItIs.
    * @param o element to be appended to this MyOwnVectorReallyItIs.
    * @return true (as per the general contract of Collection.add).
    * @since 1.2
    public synchronized boolean add(Object o) {
         modCount++;
         ensureCapacityHelper(elementCount + 1);
         elementData[elementCount++] = o;
    return true;
    * Removes the first occurrence of the specified element in this MyOwnVectorReallyItIs
    * If the MyOwnVectorReallyItIs does not contain the element, it is unchanged. More
    * formally, removes the element with the lowest index i such that
    * <code>(o==null ? get(i)==null : o.equals(get(i)))</code> (if such
    * an element exists).
    * @param o element to be removed from this MyOwnVectorReallyItIs, if present.
    * @return true if the MyOwnVectorReallyItIs contained the specified element.
    * @since 1.2
    public boolean remove(Object o) {
    return removeElement(o);
    * Inserts the specified element at the specified position in this MyOwnVectorReallyItIs.
    * Shifts the element currently at that position (if any) and any
    * subsequent elements to the right (adds one to their indices).
    * @param index index at which the specified element is to be inserted.
    * @param

  • Concurrent LRUCache?

    Hi,
    I'd like to know if you know of an LRU (least recently used) cache that would use java.util.concurrent.
    I'm currently using the following implementation that is based on java.util.LinkedHashMap.
    Do you know if there is an implementation based on java.util.concurrent.ConcurrentHashMap ?
    public class LRUCache<K, V> extends java.util.LinkedHashMap<K, V> {
        protected int maxsize;
        public LRUCache(int maxsize) {
            super(maxsize * 4 / 3 + 1, 0.75f, true);
            this.maxsize = maxsize;
        protected boolean removeEldestEntry(Map.Entry eldest) {
            return size() > maxsize;
    }

    I don't mind giving it out. Fill free to modify it or do anything you like with it. But, use this code at your own risk. I will not support it. The code is mostly undocumented. It uses a Timer that every 2 minutes checks the size and cleans out the old entries. You may need to add code to remove the TimerTask from the timer when the Map is no longer needed. I haven't since I've only used this class for static instances. It has two call back methods that can be overridden to find out what elements have been removed: removed() and expiredRemoved().
    import java.util.AbstractCollection;
    import java.util.AbstractSet;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collection;
    import java.util.Comparator;
    import java.util.Enumeration;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Set;
    import java.util.Timer;
    import java.util.TimerTask;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.ConcurrentMap;
    public class ConcurrentCacheMap<K,V> implements ConcurrentMap<K,V> {
         static final int DEFAULT_MAX_ENTRIES = 100;
         static final double PERCENT_CLEANUP = 0.05;     
         static final int DEFAULT_SEGMENTS = 16;
         static final int CHECK_DURATION = 120 * 1000;
         static final Timer timer = new Timer();
         protected int maxEntries;     
         protected ConcurrentHashMap<K,ValueWrapper<V>> map;
         /** Creates a new instance of CacheMap */
         public ConcurrentCacheMap() {
              this(DEFAULT_MAX_ENTRIES, DEFAULT_SEGMENTS);
         public ConcurrentCacheMap(int maxEntries, int concurrencyLevel) {
              map = new ConcurrentHashMap<K,ValueWrapper<V>>((maxEntries+1) * 4 / 3 + 1, 0.75f, concurrencyLevel);
              this.maxEntries = maxEntries;
              timer.schedule(new CacheCleaner(), CHECK_DURATION, CHECK_DURATION);
         public boolean replace(K key, V oldValue, V newValue) {
              return map.replace(key, new ValueWrapper<V>(oldValue), new ValueWrapper<V>(newValue));
         public V replace(K key, V value) {
              ValueWrapper<V> wrapper = map.replace(key, new ValueWrapper<V>(value));
              return checkRemove(key, wrapper);
         public V putIfAbsent(K key, V value) {
              ValueWrapper<V> wrapper = map.putIfAbsent(key, new ValueWrapper<V>(value));
              return checkRemove(key, wrapper);
         public V put(K key, V value) {
              ValueWrapper<V> wrapper = map.put(key, new ValueWrapper<V>(value));
              return checkRemove(key, wrapper);
         public void putAll(Map<? extends K,? extends V> t) {
              for (Entry<? extends K,? extends V> entry : t.entrySet()) {
                   put(entry.getKey(), entry.getValue());
         public V remove(Object key) {
              if (key == null) {
                   return null;
              ValueWrapper<V> wrapper = map.remove(key);
              return checkRemove(key, wrapper);
         public boolean remove(Object key, Object value) {
              ValueWrapper<Object> wrapper = new ValueWrapper<Object>(value);
              boolean rval = map.remove(key, wrapper);
              if (rval) {
                   removed(key, (V)value);               
              return rval;
         public V get(Object key) {
              ValueWrapper<V> wrapper = map.get(key);
              //don't increment age call .value
              return wrapper == null ? null : wrapper.getValue();
         public boolean contains(Object value) {
              return map.contains(new ValueWrapper<Object>(value));
         public boolean containsKey(Object key) {
              return map.containsKey(key);
         public boolean containsValue(Object value) {
              return map.containsValue(new ValueWrapper<Object>(value));
         public Collection<V> values() {
              return new CollectionValueWrapper();
         public Enumeration<V> elements() {
              return new ValueIter();
         public Enumeration<K> keys() {
              return new KeyIter();
         public boolean equals(Object obj) {
              if (obj instanceof ConcurrentCacheMap) {
                   return ((ConcurrentCacheMap)obj).map.equals(map);
              return false;
         public Set<K> keySet() {
              return map.keySet();
         public int size() {
              return map.size();
         public boolean isEmpty() {
              return map.isEmpty();
         public void clear() {
              map.clear();
         public String toString() {
              return map.toString();
         public int hashCode() {
              return map.hashCode();
         public Set<Entry<K, V>> entrySet() {
              return new EntrySetWrapper();
         final V checkRemove(Object key, ValueWrapper<V> wrapper) {
              if (wrapper == null){
                   return null;
              V value = wrapper.value;
              removed(key, value);
              return value;
         protected void removed(Object key, V value) {          
         protected void expiredRemoved(Object key, V value) {          
              //System.out.println(value + " " + value.getClass().getName());
         public int getMaxEntries() {
              return maxEntries;
         public void setMaxEntries(int maxEntries) {
              this.maxEntries = maxEntries;
         static boolean eq(Object o1, Object o2) {
              return (o1 == null ? o2 == null : o1.equals(o2));
         public final static class ValueWrapper<V> {
              // I just need approximate values for ageCounter so I don't care if
              // ageCounter is concurrently updated and therefore age is skipped or 
              // duplicated amoung ValueWrapper instances.  This should not be a
              // problem since I clean groups of old entries.
              // For small caches this may be a problem, but then so would be a 2 minute
              // cleanup. So if this is a concern then change ageCounter to use an AtomicLong or
              // a volatile and make schedule time variable.
              static long ageCounter;
              public V value;
              public long age;
              ValueWrapper(V value) {
                   this.value = value;
                   age = ageCounter++;
              public boolean equals(Object o) {
                   if (!(o instanceof ValueWrapper)) {
                        return false;
                   return eq(value,((ValueWrapper)o).value);
              public int hashCode() {
                   return value.hashCode();
              public V getValue() {
                   age = ageCounter++;
                   return value;
              public String toString() {
                   return value == null ? "null " : value.toString();
         abstract class Iter {
              Iterator<Entry<K,ValueWrapper<V>>> iter;
              Entry<K,ValueWrapper<V>> current;
              Iter() {
                   iter = map.entrySet().iterator();
              public void remove() {
                   ConcurrentCacheMap.this.remove(current.getKey());
              public boolean hasMoreElements() {
                   return iter.hasNext();
              public boolean hasNext() {
                   return iter.hasNext();
              final Entry<K,ValueWrapper<V>> advance() {
                   return (current = iter.next());
         final class KeyIter extends Iter implements Iterator<K>, Enumeration<K> {          
              public K nextElement() { return next(); }
              public K next() { return advance().getKey();     }
         final class ValueIter extends Iter implements Iterator<V>, Enumeration<V> {
              public V nextElement() { return next(); }                    
              public V next() {
                   ValueWrapper<V> valueWrapper = advance().getValue();
                   return valueWrapper == null ? null : valueWrapper.value;
         final class EntryIter extends Iter implements Iterator<Entry<K, V>>, Enumeration<Entry<K, V>> {               
              public Entry<K, V> nextElement() { return next(); }
              public Entry<K, V> next() { return new SimpleEntry<K,V>(advance());     }               
         final class CollectionValueWrapper extends AbstractCollection<V> {
              public Iterator<V> iterator() {
                   return new ValueIter();
              public int size() {
                   return ConcurrentCacheMap.this.size();
              public boolean contains(Object o) {
                   return ConcurrentCacheMap.this.containsValue(o);
              public void clear() {
                   ConcurrentCacheMap.this.clear();
              public Object[] toArray() {
                   Collection<V> c = new ArrayList<V>();
                   for (Iterator<V> i = iterator(); i.hasNext(); ) {
                        c.add(i.next());
                   return c.toArray();
              public <T> T[] toArray(T[] a) {
                   Collection<V> c = new ArrayList<V>();
                   for (Iterator<V> i = iterator(); i.hasNext(); ) {
                        c.add(i.next());
                   return c.toArray(a);
         final class EntrySetWrapper extends AbstractSet<Entry<K, V>> {
              public Iterator<Entry<K, V>> iterator() {
                   return new EntryIter();
              public boolean remove(Object o) {
                   if (!(o instanceof Map.Entry)) {                    
                        return false;
                   Map.Entry<K,V> entry = (Map.Entry<K,V>)o;
                   return ConcurrentCacheMap.this.remove(entry.getKey(), entry.getValue());
              public boolean contains(Object o) {
                   if (!(o instanceof Map.Entry)) {                    
                        return false;
                   Map.Entry<K,V> e = (Map.Entry<K,V>)o;
                   V v = ConcurrentCacheMap.this.get(e.getKey());
                   return v != null && v.equals(e.getValue());
              public int size() {
                   return ConcurrentCacheMap.this.size();
              public void clear() {
                   ConcurrentCacheMap.this.clear();
         final static class SimpleEntry<K,V> implements Entry<K,V> {
              Entry<K, ValueWrapper<V>> entry;
              SimpleEntry(Entry<K, ValueWrapper<V>> entry) {
                   this.entry = entry;                    
              public V setValue(V value) {
                   //don't increment age call .value
                   return entry.setValue(new ValueWrapper<V>(value)).value;
              public K getKey() {
                   return entry.getKey();
              public V getValue() {
                   ValueWrapper<V> valueWrapper = entry.getValue();                    
                   return valueWrapper == null ? null : valueWrapper.value;
              public boolean equals(Object o) {
                   if (!(o instanceof Map.Entry)) {
                        return false;
                   Entry e = (Entry)o;
                   return eq(getKey(), e.getKey()) && eq(getValue(), e.getValue());
              public int hashCode() {
                   K key = getKey();
                   V value = getValue();
                   return ((key == null)  ? 0 :   key.hashCode()) ^
                    ((value == null)   ? 0 : value.hashCode());
              public String toString() {
                   return getKey() + "=" + getValue();
         final class CacheCleaner extends TimerTask {
              public void run() {
                   try {
                        clean();
                   } catch (Throwable th) {
                        th.printStackTrace();
         public void clean() {
              int maxEntries = getMaxEntries();
              int size = size();
              if (size > maxEntries) {
                   int removeCount = (int)(maxEntries * PERCENT_CLEANUP) + (size - maxEntries);     
                   System.out.println("Starting to clean " + removeCount + " old items from cache(" + maxEntries +") with " + size + " items.");
                   long start = System.currentTimeMillis();
                   //Size can and will likely change during coping to an array inside of toArray
                   //and and new array will likely be need to be created. So to prevent three
                   //large arrays from being allocated. Just allocate an empty array for type purposes.
                   Entry[] allItem = new Entry[0]; 
                   allItem = map.entrySet().toArray(allItem);
                   Arrays.sort(allItem, new EntrySetComparator<K,V>());
                   int upper = allItem.length;
                   for (int i=0; i<removeCount; i++) {
                        Entry<K, ValueWrapper<V>> entry = (Entry<K, ValueWrapper<V>>)allItem;
                        ValueWrapper<V> valueWrapper = entry.getValue();
                        remove(entry.getKey());
                        if (valueWrapper != null) {
                             expiredRemoved(entry.getKey(), valueWrapper.value);
                   System.out.println("Cache(" + maxEntries +") took " + (System.currentTimeMillis() - start) + " ms to clean " + removeCount + " items");
         static final class EntrySetComparator<K,V> implements Comparator<Entry<K, ValueWrapper<V>>> {
              public int compare(Entry<K, ValueWrapper<V>> o1, Entry<K, ValueWrapper<V>> o2) {
                   ValueWrapper<V> valueWrapper1 = o1.getValue();
                   long age1 = valueWrapper1 != null ?
                        valueWrapper1.age :
                        -1;
                   ValueWrapper<V> valueWrapper2 = o2.getValue();
                   long age2 = valueWrapper2 != null ?
                        valueWrapper2.age :
                        -1;
                   int rval= age1 > age2 ?
                        1 :     
                        age1 == age2 ?
                             0 :
                             -1;
                   return rval;
    //perform a simple santity test.
         public static void main(String ...args) {
              final ConcurrentCacheMap<Integer,String> cache = new ConcurrentCacheMap<Integer,String>(300000,16);
              new Thread() {
                   public void run() {
                        int negCounter = -1;
                        for (;;) {
                             cache.put(negCounter, Integer.toString(negCounter));
                             negCounter--;
                             try {
                                  Thread.sleep(10);
                             } catch (InterruptedException ex){
                                  Thread.currentThread().interrupt();
                                  return;
              }.start();
              int counter = 0;
              for (int i=0; i<301000; i++) {
                   counter++;
                   cache.put(counter,Integer.toString(counter));
              for (int i=0; i<20; i++) {
                   cache.clean();
                   for (int j=0; j<16000; j++) {
                        counter++;
                        cache.put(counter,Integer.toString(counter));
              System.exit(0);

Maybe you are looking for

  • How to remove some columns from an existing table?

    Let's say my table's structure is as follows: Table name: EMPLOYEE Columns: Name, Birthdate, Gender, Salary, Hometown, Language and so on. There are data in the table. Now I want to remove columns Hometown and Language, and I don't care the data loss

  • Checkbox cant be updated in ALV Grid

    Hi in my requirement, ALV Grid contains checkbox, when I check that, the internal table for checkbox is not updated. In code I am writting: Final Internal Tbale: Data:   BEGIN OF T_FINAL occurs 0,         CHK_BOX,         END OF T_FINAL.   LS_FIELDCA

  • Urgent: Data Load Failure

    Hi, Delta from cube to ODS failed. It gives following error: DataSource 8SL_ODS5 has to be replicated (time stamp, see long text)     @35@ DataSource 8SL_ODS5 has to be replicated (time stamp, see long text) Message no. R3016 Diagnosis DataSource 8SL

  • How to configure a link in a popup window to open a tab in main window.

    I have put videos in popup windows with a link to their relevant main windows. I have used a behaviors extention from adobe to close the popup with the same link button, but the page doesn't open in the main window. Here is the link: <h2><a href="htt

  • Safari 5 display size?

    Every time I open Safari 5 in Windows 7 Professional I have to Zoom in twice to get a suitable display size on my google.com homepage. Even adjusting the two font sizes in Preferences/Appearance has no apparent effect. Also, what's the simplest way t