alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (ArrayTable.java)

This example Java source code file (ArrayTable.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

array_boundary, arraytable, clientpropertykey, cloneable, enumeration, hashtable, ioexception, object, serializable, util

The ArrayTable.java Java example source code

/*
 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package javax.swing;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.Hashtable;

/*
 * Private storage mechanism for Action key-value pairs.
 * In most cases this will be an array of alternating
 * key-value pairs.  As it grows larger it is scaled
 * up to a Hashtable.
 * <p>
 * This does no synchronization, if you need thread safety synchronize on
 * another object before calling this.
 *
 * @author Georges Saab
 * @author Scott Violet
 */
class ArrayTable implements Cloneable {
    // Our field for storage
    private Object table = null;
    private static final int ARRAY_BOUNDARY = 8;


    /**
     * Writes the passed in ArrayTable to the passed in ObjectOutputStream.
     * The data is saved as an integer indicating how many key/value
     * pairs are being archived, followed by the the key/value pairs. If
     * <code>table is null, 0 will be written to s.
     * <p>
     * This is a convenience method that ActionMap/InputMap and
     * AbstractAction use to avoid having the same code in each class.
     */
    static void writeArrayTable(ObjectOutputStream s, ArrayTable table) throws IOException {
        Object keys[];

        if (table == null || (keys = table.getKeys(null)) == null) {
            s.writeInt(0);
        }
        else {
            // Determine how many keys have Serializable values, when
            // done all non-null values in keys identify the Serializable
            // values.
            int validCount = 0;

            for (int counter = 0; counter < keys.length; counter++) {
                Object key = keys[counter];

                /* include in Serialization when both keys and values are Serializable */
                if (    (key instanceof Serializable
                         && table.get(key) instanceof Serializable)
                             ||
                         /* include these only so that we get the appropriate exception below */
                        (key instanceof ClientPropertyKey
                         && ((ClientPropertyKey)key).getReportValueNotSerializable())) {

                    validCount++;
                } else {
                    keys[counter] = null;
                }
            }
            // Write ou the Serializable key/value pairs.
            s.writeInt(validCount);
            if (validCount > 0) {
                for (Object key : keys) {
                    if (key != null) {
                        s.writeObject(key);
                        s.writeObject(table.get(key));
                        if (--validCount == 0) {
                            break;
                        }
                    }
                }
            }
        }
    }


    /*
     * Put the key-value pair into storage
     */
    public void put(Object key, Object value){
        if (table==null) {
            table = new Object[] {key, value};
        } else {
            int size = size();
            if (size < ARRAY_BOUNDARY) {              // We are an array
                if (containsKey(key)) {
                    Object[] tmp = (Object[])table;
                    for (int i = 0; i<tmp.length-1; i+=2) {
                        if (tmp[i].equals(key)) {
                            tmp[i+1]=value;
                            break;
                        }
                    }
                } else {
                    Object[] array = (Object[])table;
                    int i = array.length;
                    Object[] tmp = new Object[i+2];
                    System.arraycopy(array, 0, tmp, 0, i);

                    tmp[i] = key;
                    tmp[i+1] = value;
                    table = tmp;
                }
            } else {                 // We are a hashtable
                if ((size==ARRAY_BOUNDARY) && isArray()) {
                    grow();
                }
                ((Hashtable<Object,Object>)table).put(key, value);
            }
        }
    }

    /*
     * Gets the value for key
     */
    public Object get(Object key) {
        Object value = null;
        if (table !=null) {
            if (isArray()) {
                Object[] array = (Object[])table;
                for (int i = 0; i<array.length-1; i+=2) {
                    if (array[i].equals(key)) {
                        value = array[i+1];
                        break;
                    }
                }
            } else {
                value = ((Hashtable)table).get(key);
            }
        }
        return value;
    }

    /*
     * Returns the number of pairs in storage
     */
    public int size() {
        int size;
        if (table==null)
            return 0;
        if (isArray()) {
            size = ((Object[])table).length/2;
        } else {
            size = ((Hashtable)table).size();
        }
        return size;
    }

    /*
     * Returns true if we have a value for the key
     */
    public boolean containsKey(Object key) {
        boolean contains = false;
        if (table !=null) {
            if (isArray()) {
                Object[] array = (Object[])table;
                for (int i = 0; i<array.length-1; i+=2) {
                    if (array[i].equals(key)) {
                        contains = true;
                        break;
                    }
                }
            } else {
                contains = ((Hashtable)table).containsKey(key);
            }
        }
        return contains;
    }

    /*
     * Removes the key and its value
     * Returns the value for the pair removed
     */
    public Object remove(Object key){
        Object value = null;
        if (key==null) {
            return null;
        }
        if (table !=null) {
            if (isArray()){
                // Is key on the list?
                int index = -1;
                Object[] array = (Object[])table;
                for (int i = array.length-2; i>=0; i-=2) {
                    if (array[i].equals(key)) {
                        index = i;
                        value = array[i+1];
                        break;
                    }
                }

                // If so,  remove it
                if (index != -1) {
                    Object[] tmp = new Object[array.length-2];
                    // Copy the list up to index
                    System.arraycopy(array, 0, tmp, 0, index);
                    // Copy from two past the index, up to
                    // the end of tmp (which is two elements
                    // shorter than the old list)
                    if (index < tmp.length)
                        System.arraycopy(array, index+2, tmp, index,
                                         tmp.length - index);
                    // set the listener array to the new array or null
                    table = (tmp.length == 0) ? null : tmp;
                }
            } else {
                value = ((Hashtable)table).remove(key);
            }
            if (size()==ARRAY_BOUNDARY - 1 && !isArray()) {
                shrink();
            }
        }
        return value;
    }

    /**
     * Removes all the mappings.
     */
    public void clear() {
        table = null;
    }

    /*
     * Returns a clone of the <code>ArrayTable.
     */
    public Object clone() {
        ArrayTable newArrayTable = new ArrayTable();
        if (isArray()) {
            Object[] array = (Object[])table;
            for (int i = 0 ;i < array.length-1 ; i+=2) {
                newArrayTable.put(array[i], array[i+1]);
            }
        } else {
            Hashtable<?,?> tmp = (Hashtable)table;
            Enumeration<?> keys = tmp.keys();
            while (keys.hasMoreElements()) {
                Object o = keys.nextElement();
                newArrayTable.put(o,tmp.get(o));
            }
        }
        return newArrayTable;
    }

    /**
     * Returns the keys of the table, or <code>null if there
     * are currently no bindings.
     * @param keys  array of keys
     * @return an array of bindings
     */
    public Object[] getKeys(Object[] keys) {
        if (table == null) {
            return null;
        }
        if (isArray()) {
            Object[] array = (Object[])table;
            if (keys == null) {
                keys = new Object[array.length / 2];
            }
            for (int i = 0, index = 0 ;i < array.length-1 ; i+=2,
                     index++) {
                keys[index] = array[i];
            }
        } else {
            Hashtable<?,?> tmp = (Hashtable)table;
            Enumeration<?> enum_ = tmp.keys();
            int counter = tmp.size();
            if (keys == null) {
                keys = new Object[counter];
            }
            while (counter > 0) {
                keys[--counter] = enum_.nextElement();
            }
        }
        return keys;
    }

    /*
     * Returns true if the current storage mechanism is
     * an array of alternating key-value pairs.
     */
    private boolean isArray(){
        return (table instanceof Object[]);
    }

    /*
     * Grows the storage from an array to a hashtable.
     */
    private void grow() {
        Object[] array = (Object[])table;
        Hashtable<Object, Object> tmp = new Hashtable(array.length/2);
        for (int i = 0; i<array.length; i+=2) {
            tmp.put(array[i], array[i+1]);
        }
        table = tmp;
    }

    /*
     * Shrinks the storage from a hashtable to an array.
     */
    private void shrink() {
        Hashtable<?,?> tmp = (Hashtable)table;
        Object[] array = new Object[tmp.size()*2];
        Enumeration<?> keys = tmp.keys();
        int j = 0;

        while (keys.hasMoreElements()) {
            Object o = keys.nextElement();
            array[j] = o;
            array[j+1] = tmp.get(o);
            j+=2;
        }
        table = array;
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java ArrayTable.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.