Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Dynamic array of primitive types

Posted on 2002-06-06
19
Medium Priority
?
828 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 12
  • 3
  • 3
  • +1
19 Comments
 
LVL 7

Expert Comment

by:Igor Bazarny
ID: 7060001
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
ID: 7060894
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
ID: 7061594
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:ylyip
ID: 7062029
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 400 total points
ID: 7062434

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
ID: 7073520
0
 
LVL 9

Expert Comment

by:doronb
ID: 7073523
0
 
LVL 9

Expert Comment

by:doronb
ID: 7073526
0
 
LVL 9

Expert Comment

by:doronb
ID: 7073530
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
 
LVL 9

Expert Comment

by:doronb
ID: 7073532
0
 
LVL 9

Expert Comment

by:doronb
ID: 7073536
0
 
LVL 9

Expert Comment

by:doronb
ID: 7073538
0
 
LVL 9

Expert Comment

by:doronb
ID: 7073557
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
ID: 7073560
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
ID: 7073566
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
ID: 7073568
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
ID: 7074502
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 400 total points
ID: 7074830
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
ID: 8834142
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

Tech or Treat! - Giveaway

Submit an article about your scariest tech experience—and the solution—and you’ll be automatically entered to win one of 4 fantastic tech gadgets.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
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 if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
This video teaches viewers about errors in exception handling.
Suggested Courses

609 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