Solved

Dynamic array of primitive types

Posted on 2002-06-06
19
799 Views
Last Modified: 2008-02-01
Hi all,

I always encounter the situation to read an unknown number of primitive values, like int or float. I don't want to create wrapper objects and put them into ArrayList or Vector because it takes longer time and larger space. Is there any way to tackle the problem?

Thanks in advance.
0
Comment
Question by:ylyip
  • 12
  • 3
  • 3
  • +1
19 Comments
 
LVL 7

Expert Comment

by:Igor Bazarny
Comment Utility
Hi,

You can recreate ArrayList behaviour. Something like:

public class IntVector{
    private int[] content = new int[10];
    private int used = 0;

    public int get(int index){
        if(i<0 || i>=used){
             throw new ArrayIndexOutOfBoundsException("wrong index: "+index)
        }
        return content[i];
    }

    public void add(int i){
        if( used == content.length ){
            int[] expanded = new int[content.length*2];
            System.arraycopy(content,0,expanded,0,content.length);
            content = expanded;
        }
    }

    public int size(){
        return used;
    }
    // etc.
    // Take care of synchronization if you are going to use same instance from multiple threads.
}

Regards,
Igor Bazarny,
Brainbench MVP for Java 1
0
 
LVL 1

Author Comment

by:ylyip
Comment Utility
Thanks Bazarny, but is there a more generic solution? I mean this time if I need dynamic int array, I write one class, next time when I need dynamic float array, I write another one. Just another time I need a HashMap-like structure with int keys, another more complicated one. Do the standard packages of Java (perhaps in the new 1.4) contain any class for the purpose?
0
 
LVL 7

Expert Comment

by:Igor Bazarny
Comment Utility
Hi,

I'm afraid there is no ready to use solution. Besides, I don't think you need something more complicated than array. HashMap would anyway need at least one object per entry, so wrapping primitive would not be a big performance hit. Besides, for ints you could cache, say, first 100 and reuse instances:

class IntWrapper{

Integer cache = new Integer[100];

public Integer wrap(int value){
    if(value <0 || value >= cache.length){
        return new Integer(value);
    }
    if( cache[value] == null ){
        cache[value] = new Integer(value);
    }
    return cache[value];
}

Regards,
Igor Bazarny
0
 
LVL 1

Author Comment

by:ylyip
Comment Utility
Bazarny, thanks for your comment. I am dealing with very large datasets, with up to several hundred thousands of records and up to several thousands attributes per record. Therefore I need to save as much memory as possible, so caching does not seem feasible.
0
 
LVL 7

Accepted Solution

by:
Igor Bazarny earned 100 total points
Comment Utility

OK, but I'm still not sure that primitive-based HashMap would be helpful. Array is quite easy thing, try to stick with array as long as you can. Actually, you may create array of long's and use it for any primitives (check out Double.doubleToLongBits() method). Or array of ints and array of longs and use first one for floats, ints, chars and bytes and second for doubles and longs.

Possibly you need to review your algorithms. Do you really need all the data all the time? Maybe you can split your data into pieces, maybe you can put cache to the file. Check out java.nio package, new in 1.4 version, especially java.nio.channels.FileChannel for efficient file io.

Regards,
Igor Bazarny
0
 
LVL 9

Expert Comment

by:doronb
Comment Utility
0
 
LVL 9

Expert Comment

by:doronb
Comment Utility
0
 
LVL 9

Expert Comment

by:doronb
Comment Utility
0
 
LVL 9

Expert Comment

by:doronb
Comment Utility
Hi,


There's an error and my source-code doesn't go in.. Email me at doronbarak@hotmail.com to get a source-code for a generic Argument class..


Doron
0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 9

Expert Comment

by:doronb
Comment Utility
0
 
LVL 9

Expert Comment

by:doronb
Comment Utility
0
 
LVL 9

Expert Comment

by:doronb
Comment Utility
0
 
LVL 9

Expert Comment

by:doronb
Comment Utility
Hi,


Ok, I'll try posting in the code for the generic wrapper in chunks:

import java.lang.reflect.Array;

public class Argument {
     private Object array;
     private Class currentClass;

     private Argument(Class objClass) {
          array = null;
          currentClass = null;
          checkType(objClass);
     }

     private void checkType(Class objClass) {
          if (objClass != currentClass) {
               currentClass = objClass;
               array = Array.newInstance(currentClass, 1);
          }
     }

     public Object getValue() {
          return Array.get(array, 0);
     }

     public void setValue(Object value) {
          currentClass = null;          
          array = value;
     }

To be continued...
0
 
LVL 9

Expert Comment

by:doronb
Comment Utility
Ok, lets try the "setValue" part:

     public void setValue(boolean value) {
          checkType(boolean.class);
          Array.setBoolean(array, 0, value);
     }

     public void setValue(byte value) {
          checkType(byte.class);
          Array.setByte(array, 0, value);
     }

     public void setValue(char value) {
          checkType(char.class);
          Array.setChar(array, 0, value);
     }

     public void setValue(double value) {
          checkType(double.class);
          Array.setDouble(array, 0, value);
     }

     public void setValue(float value) {
          checkType(float.class);
          Array.setFloat(array, 0, value);
     }

     public void setValue(int value) {
          checkType(int.class);
          Array.setInt(array, 0, value);
     }

     public void setValue(long value) {
          checkType(long.class);
          Array.setLong(array, 0, value);
     }

     public void setValue(short value) {
          checkType(short.class);
          Array.setShort(array, 0, value);
     }

To be continued...
0
 
LVL 9

Expert Comment

by:doronb
Comment Utility
Ok, now the "getXXXX" part:

     public static char getChar(Object obj) {
          return ((Character)getObject(obj)).charValue();
     }

     public static boolean getBoolean(Object obj) {
          return ((Boolean)getObject(obj)).booleanValue();
     }

     public static byte getByte(Object obj) {
          return ((Byte)getObject(obj)).byteValue();
     }

     public static double getDouble(Object obj) {
          return ((Double)getObject(obj)).doubleValue();
     }

     public static float getFloat(Object obj) {
          return ((Float)getObject(obj)).floatValue();
     }

     public static int getInteger(Object obj) {
          return ((Integer)getObject(obj)).intValue();
     }

     public static long getLong(Object obj) {
          return ((Long)getObject(obj)).longValue();
     }

     public static short getShort(Object obj) {
          return ((Short)getObject(obj)).shortValue();
     }

     public static Object getObject(Object obj) {
          return (obj instanceof Argument) ? ((Argument)obj).getValue() : obj;
     }

To be continued...
0
 
LVL 9

Expert Comment

by:doronb
Comment Utility
Last part:

     public static Argument set(boolean value) {
          Argument o = new Argument(boolean.class);
          o.setValue(value);
          return o;
     }

     public static Argument set(byte value) {
          Argument o = new Argument(byte.class);
          o.setValue(value);
          return o;
     }

     public static Argument set(char value) {
          Object o = new Argument(char.class);
          o.setValue(value);
          return o;
     }

     public static Argument set(double value) {
          Argument o = new Argument(double.class);
          o.setValue(value);
          return o;
     }

     public static Argument set(float value) {
          Argument o = new Argument(float.class);
          o.setValue(value);
          return o;
     }

     public static Argument set(int value) {
          Argument o = new Argument(int.class);
          o.setValue(value);
          return o;
     }

     public static Argument set(long value) {
          Argument o = new Argument(long.class);
          o.setValue(value);
          return o;
     }

     public static Argument set(short value) {
          Argument o = new Argument(short.class);
          o.setValue(value);
          return o;
     }
}

Now you can use the "set(...)" static method to wrap any Java native data type.


Hope this helps,
Doron
0
 
LVL 1

Author Comment

by:ylyip
Comment Utility
Doron, thanks for your code. It is a generic wrapper class of primitive types. But it does not seem to solve my problem. If I have an unknown number of primitive values from a source, say a file, I still need to create a lot of objects if the Argument class is used.

The suggestion of bazarny to write a dynamic array class looks closer to the problem.
0
 
LVL 9

Assisted Solution

by:doronb
doronb earned 100 total points
Comment Utility
ylyip, if you combine my code with bazarny's you'd get something like this:

class Wrapper {

Argument cache = new Argument[100];

private int calculateIndex(XXXX value) {
   int index = -1;
   // Calculate the index for this specific type of data..
   return index;
}

public Argument wrap(XXXXX value) {
   // Find where the data should be..
   int index = calculateIndex(value);
   // Check to see if it's in the cache..
   if (index < 0 || index >= cache.length) {
      // Return a new wrapped Argument..
      return Argument.set(value);
   }
   // Is the cache entry empty?
   if (cache[index] == null) {
       // Create and store a new Argument..
       cache[index] = Argument.set(value);
   }
   return cache[index];
}

Of course you'll have to implement the wrap(...) and calculateIndex(...) methods for every native data type like I did in my Argument class, but using this wrapper ensures that you have a generic wrapper with caching for any data type.


Hope this helps,

Doron
0
 
LVL 35

Expert Comment

by:girionis
Comment Utility
No comment has been added lately, so it's time to clean up this TA.

I will leave a recommendation in the Cleanup topic area that this question is:

- split points between bazarny@idg and doronb

Please leave any comments here within the
next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER !

girionis
Cleanup Volunteer
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
countAbc challenge 9 49
strCopies  challenge 17 73
maven java path setting 5 49
Free Alternative to JIRA 4 52
Java had always been an easily readable and understandable language.  Some relatively recent changes in the language seem to be changing this pretty fast, and anyone that had not seen any Java code for the last 5 years will possibly have issues unde…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now