how to write array elements to console

Discussion in 'Java' started by Dzikus, Dec 13, 2006.

  1. Dzikus

    Dzikus Guest

    Hello,
    I have following problem:
    Let's assume there is a function
    f(Object obj){
    ...
    }
    And if obj is an array (of some primitive types) I want to write
    elements to Sysytem.out

    For example if I have:
    int[] array = {1, 2, 3, 4};
    f(array);

    The expected result would be
    1
    2
    3
    4
    Does anybody knows how to do it?

    Thanks in advance
    Dominik
    Dzikus, Dec 13, 2006
    #1
    1. Advertising

  2. Dzikus wrote:
    > Hello,
    > I have following problem:

    ....
    > And if obj is an array (of some primitive types) I want to write
    > elements to Sysytem.out

    .....
    > Does anybody knows how to do it?


    Yes, of course! Doesn't your textbook cover loops?
    Or is it that you simply have not bothered consulting
    your textbook, and would prefer us to do your homework?

    Andrew T.
    Andrew Thompson, Dec 13, 2006
    #2
    1. Advertising

  3. Dzikus

    Dzikus Guest

    This is not a homework :> I'm C++/C programmer and I'm not very
    familiar with reflection and other more Java - specific conveniences.

    The type of f's argument is Object, not array.
    There is a function isArray (java.lang.Class) byt still i dont know of
    what types the array is (in order to downcast for example)...

    Andrew Thompson napisal(a):
    >
    > Yes, of course! Doesn't your textbook cover loops?
    > Or is it that you simply have not bothered consulting
    > your textbook, and would prefer us to do your homework?
    >
    > Andrew T.
    Dzikus, Dec 13, 2006
    #3
  4. Dzikus

    Dzikus Guest

    Maybe i'll put whole code for better understanding:
    I'm looking for more generic solution for writing all types of arrays,
    not only byte array ...

    public aspect Debug {
    pointcut Call() : (execution(* *(..)) || call(* *(..))
    || execution(*.new()))
    && !within(Debug);
    synchronized void write(JoinPoint jp)
    {
    System.out.println(jp.getSignature());

    Object[] args = jp.getArgs();
    if (args.length > 0) {
    System.out.println("Arguments: ");
    String[] names = ((CodeSignature) jp.getSignature())
    .getParameterNames();
    Class[] types = ((CodeSignature) jp.getSignature())
    .getParameterTypes();
    for (int i = 0; i < args.length; i++) {
    System.out.println(" " + i + ". " + names + " : "
    + types.getName() + " = " + args);
    if(types.getName().compareTo("[B") == 0)
    {
    System.out.print("Byte table:");
    byte[] data = (byte[])(args);
    for(int j = 0; j < data.length; ++j){
    System.out.print(data[j]);
    }
    System.out.println("");
    }
    }
    }
    System.out.println("=====================================");
    }
    before() : Call() {
    write(thisJoinPoint);
    }

    }
    Dzikus, Dec 13, 2006
    #4
  5. Dzikus

    Alex Hunsley Guest

    Dzikus wrote:
    > Hello,
    > I have following problem:
    > Let's assume there is a function
    > f(Object obj){
    > ...
    > }
    > And if obj is an array (of some primitive types) I want to write
    > elements to Sysytem.out
    >
    > For example if I have:
    > int[] array = {1, 2, 3, 4};
    > f(array);
    >
    > The expected result would be
    > 1
    > 2
    > 3
    > 4
    > Does anybody knows how to do it?


    Assuming this isn't homework (it doesn't look like it)...
    It can't be done this way, because you can't pass int array (int[]) into
    a method expecting an Object. They just don't match.
    Alternatives:

    1) write your f method to expect an Object array (Object[]) and pass in
    an array of Integer objects (*not* primitive ints!)
    i.e.
    f(Object[] obj){
    ...
    }


    Integer int[] array = {new Integer(1), new Integer(2), ....};
    f(array);

    2) write your f method to take specifically an int array

    HTH,
    lex
    Alex Hunsley, Dec 13, 2006
    #5
  6. Dzikus

    Alex Hunsley Guest

    Dzikus wrote:
    > Maybe i'll put whole code for better understanding:
    > I'm looking for more generic solution for writing all types of arrays,
    > not only byte array ...
    >


    Now you're asking the smart question! Much better than the limited
    question you posted before.
    As I suggested, make your f method take an array of Objects.
    Then call .toString() on each of those objects in that method and print
    out the result. (You'll need each object you've written yourself to have
    a toString() method that returns sensible string output. Lookup
    Object.toString() for more info.)
    lex
    Alex Hunsley, Dec 13, 2006
    #6
  7. Dzikus

    Dzikus Guest


    > It can't be done this way, because you can't pass int array (int[]) into
    > a method expecting an Object. They just don't match.


    What do you mean they don't match?
    The following example compiles and works...

    private void f(Object o){
    System.out.println("Hello");
    }
    private void g(){
    int[] ala = {1,2,3};
    f(ala);
    }
    Dzikus, Dec 13, 2006
    #7
  8. Dzikus

    Guest

    Dzikus wrote:
    > Hello,
    > I have following problem:
    > Let's assume there is a function
    > f(Object obj){
    > ...
    > }
    > And if obj is an array (of some primitive types) I want to write
    > elements to Sysytem.out
    >
    > For example if I have:
    > int[] array = {1, 2, 3, 4};
    > f(array);
    >
    > The expected result would be
    > 1
    > 2
    > 3
    > 4
    > Does anybody knows how to do it?


    If you are using Java 5(+), and you dont mind if the output is in the
    format: 1, 2, 3, 4, 5 (because you are just wanting to display the
    values to a user), then you can use the toString method on the Arrays
    utility class.
    , Dec 13, 2006
    #8
  9. Dzikus

    Dzikus Guest

    Yeah, it's a great hint.
    But still I have somehow downcast from Object to array of specified
    type ...
    Dzikus, Dec 13, 2006
    #9
  10. Dzikus

    Eric Sosman Guest

    Dzikus wrote:
    > Hello,
    > I have following problem:
    > Let's assume there is a function
    > f(Object obj){
    > ...
    > }
    > And if obj is an array (of some primitive types) I want to write
    > elements to Sysytem.out
    >
    > For example if I have:
    > int[] array = {1, 2, 3, 4};
    > f(array);
    >
    > The expected result would be
    > 1
    > 2
    > 3
    > 4
    > Does anybody knows how to do it?


    void f(Object obj) {
    // optional test
    if (! obj.getClass().isArray())
    throw new IllegalArgumentException("not array");

    if (obj instanceof int[]) {
    int[] arr = (int[])obj;
    ...
    } else if (obj instanceof long[]) {
    long[] arr = (long[])obj;
    ...
    } else if ...
    ...
    else
    throw new IllegalArgumentException("phphhbbbh!");
    }

    A slightly different approach might look like

    void f(Object obj) {
    String className = obj.getClass().getName();
    if (className.charAt(0) != '[')
    throw new IllegalArgumentException("not array");
    switch (className.charAt(1)) {
    case 'I':
    int[] iarray = (int[])obj;
    ...
    break;
    case 'J':
    long[] larray = (long[])obj;
    ...
    break;
    ...
    default:
    throw new IllegalArgumentException("phphhbbbh!");
    }
    }

    Still another approach would be to change the way the method
    is defined. Instead of writing one method to handle every possible
    type of array, write a method for each array type you care about
    and let the compiler figure out which to call:

    void f(int[] array) { ... }
    void f(long[] array) { ... }
    ...

    However, this approach only works if you actually know the array
    type at compile time, that is, if you actually have an int[]
    reference or a long[] reference or whatever at the point when you
    make the call. If you really, truly have an Object reference and
    nothing more, you need to make the determination at run time.

    --
    Eric Sosman
    lid
    Eric Sosman, Dec 13, 2006
    #10
  11. Dzikus

    Guest

    Dzikus wrote:
    > Yeah, it's a great hint.
    > But still I have somehow downcast from Object to array of specified
    > type ...


    It's not trivial to do this, but it's more tedious than difficult
    to handle an arbitrary input object if you allow a
    recursive solution.

    I believe you are correct that you will have to do explicit downcasts
    to each of the primitive types. You may also want to handle
    arrays of objects specially (which will get you multi-dimensional
    arrays of all types as well).

    E.g.,

    void method(Object o) {

    if (o instanceof Object[]) {
    Object[] oa = (Object[]) o;
    for (Object ox: oa) method(ox);
    } else if (o instanceof int[]) {
    ... process int array ..
    } else if (o instanceof double[]) {
    ... handle all 7 primitive arrays explictly
    } else {
    ... Handle a non-array Object
    }
    }

    This is one example where it would be nice to have double-dispatch but
    that's not available in Java. [Double dispatch would allow you to
    select from among overloaded 'method's the one whose signature
    matched the actual rather than the declared class of the argument.]

    Regards,
    Tom McGlynn
    , Dec 13, 2006
    #11
  12. Dzikus

    Dzikus Guest

    > If you really, truly have an Object reference and
    > nothing more, you need to make the determination at run time.
    >

    This is what I am looking for. I suspect that in such powerfull
    language like java it is possible to avoid those switch - cases with
    downcasting.
    How can I do such determination?
    Dzikus, Dec 13, 2006
    #12
  13. Dzikus

    Eric Sosman Guest

    Dzikus wrote:
    >> If you really, truly have an Object reference and
    >> nothing more, you need to make the determination at run time.
    >>

    > This is what I am looking for. I suspect that in such powerfull
    > language like java it is possible to avoid those switch - cases with
    > downcasting.
    > How can I do such determination?


    In either of the ways I showed, or perhaps in some other
    way I didn't think of: I'm only a user of Java, not a guru.
    The documentation for java.lang.Class is likely to be helpful.

    One way or another, you will need to determine the actual
    class of the array your Object reference refers to. You said
    you only cared about arrays of primitive types, which makes
    things a little easier: There is a fixed number of primitive
    types to check for, and writing the code for each of them (or
    for the subset that interests you) may take you a few minutes
    but doesn't require much ingenuity.

    --
    Eric Sosman
    lid
    Eric Sosman, Dec 13, 2006
    #13
  14. Dzikus

    Oliver Wong Guest

    "Dzikus" <> wrote in message
    news:...
    > Hello,
    > I have following problem:
    > Let's assume there is a function
    > f(Object obj){
    > ...
    > }
    > And if obj is an array (of some primitive types) I want to write
    > elements to Sysytem.out
    >
    > For example if I have:
    > int[] array = {1, 2, 3, 4};
    > f(array);
    >
    > The expected result would be
    > 1
    > 2
    > 3
    > 4
    > Does anybody knows how to do it?


    Here's a solution that does not do any downcasting, nor use any switch
    statement. However, it does use an exception for control flow, which is
    somewhat frowned upon.

    <SSCCE>
    import java.lang.reflect.Array;

    public class ArrayTest {
    public static void main(String[] args) {
    f(new int[] { 1, 2, 3 });
    f(new byte[] { 4, 5, 6 });
    f(new char[] { 'a', 'b', 'c' });
    }

    public static void f(Object o) throws IllegalArgumentException {
    if (!o.getClass().isArray()) {
    throw new IllegalArgumentException("Not an array.");
    }
    int index = 0;
    try {
    while (true) {
    System.out.println(Array.get(o, index));
    index++;
    }
    }
    catch (ArrayIndexOutOfBoundsException aioobe) {
    // do nothing
    }
    }
    }

    </SSCCE>

    The issue is that I can't figure out how to get the length of the array
    without performing a cast. The following does not work:

    o.getClass().getField("length").getInt(o);

    It throws a NoSuchFieldException, which surprises me, because I'm pretty
    sure arrays have a field called "length". But maybe it has to do with the
    fact that arrays are somewhat "magical" and not pure objects?

    - Oliver
    Oliver Wong, Dec 13, 2006
    #14
  15. Dzikus

    Dzikus Guest

    Thanks for help.
    This is what I was looking for :)
    Array length we can get using Array.getLength function.

    import java.lang.reflect.Array;
    class ArrayTest{
    public static void f(Object o) {
    Class c =o.getClass();
    if(c.isArray()){
    for(int i = 0; i < Array.getLength(o); ++i){
    System.out.println(Array.get(o, i));
    }
    }
    }

    public static void main(String[] args) {
    f(new int[] { 1, 2, 3 });
    f(new byte[] { 4, 5, 6 });
    f(new char[] { 'a', 'b', 'c' });
    }
    }
    Dzikus, Dec 13, 2006
    #15
  16. Dzikus

    Lew Guest

    Alex Hunsley wrote:
    >> It can't be done this way, because you can't pass int array (int[]) into
    >> a method expecting an Object. They just don't match.


    Dzikus wrote:
    > What do you mean they don't match?
    > The following example compiles and works...
    >
    > private void f(Object o){
    > System.out.println("Hello");
    > }
    > private void g(){
    > int[] ala = {1,2,3};
    > f(ala);
    > }


    They do so match!

    Dzikus, you're entirely correct. Array types are subtypes of Object, and can
    be upcast without fear. Downcasting works if the Object happens to be an array
    at runtime for the downcast.

    What you did, testing the claim, exemplifies wise use of Usenet.

    There's a lot of reflection and C++ idiom in your posted code, so I didn't
    delve into it much. To answer your original question, how to print an array
    from a method that takes an Object parameter:

    Another poster suggested simply using the parameter's toString() method, which
    you can do implicitly or explicitly.

    private PrintWriter out;
    ....
    public void foo( Object obj )
    {
    out.println( "Object: " );
    out.println( obj );
    }

    If you don't like the way the arrays' toString() methods work, you can crack
    arrays into a loop. This requires a check for each primitive type and Object
    if you're avoiding complicated reflection:

    public void foo( Object obj )
    {
    if ( obj instanceof Object [] )
    {
    Object [] oarr = (Object []) obj;
    for( Object o : oarr )
    {
    out.println( o );
    }
    }
    else if ( obj instanceof int [] )
    {
    int [] iarr = (int []) obj;
    for ( int i : iarr )
    {
    out.println( i );
    }
    }
    // ... byte, char, short, long, float, double
    else
    {
    out.println( obj );
    }
    out.flush();
    }

    As another poster pointed out, in a type that you design a reasonable
    implementation of toString() is important.

    Even better is when you know that you'll use only arrays of a type that you
    design (or subtype thereof). Then you can simplify to a static method of, say,
    parent class Foo that can print values of Foo [] as you like. If the array
    lister method calls each element's own toString() then the whole listing will
    be sensible.

    - Lew
    Lew, Dec 13, 2006
    #16
  17. Dzikus

    Oliver Wong Guest

    "Dzikus" <> wrote in message
    news:...
    >
    > Array length we can get using Array.getLength function.


    I can't believe I missed that function.

    Oh well. Hooray for teamwork! =)

    - Oliver
    Oliver Wong, Dec 13, 2006
    #17
  18. Dzikus

    Alex Hunsley Guest

    Lew wrote:
    > Alex Hunsley wrote:
    >>> It can't be done this way, because you can't pass int array (int[]) into
    >>> a method expecting an Object. They just don't match.

    >
    > Dzikus wrote:
    >> What do you mean they don't match?
    >> The following example compiles and works...
    >>
    >> private void f(Object o){
    >> System.out.println("Hello");
    >> }
    >> private void g(){
    >> int[] ala = {1,2,3};
    >> f(ala);
    >> }

    >
    > They do so match!
    >
    > Dzikus, you're entirely correct. Array types are subtypes of Object, and
    > can be upcast without fear. Downcasting works if the Object happens to
    > be an array at runtime for the downcast.


    Whoops, my bad! That'll teach me to not double check....
    lex
    Alex Hunsley, Dec 18, 2006
    #18
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Peter Hansen
    Replies:
    1
    Views:
    373
    Joona I Palaste
    Aug 24, 2003
  2. Peter Hansen
    Replies:
    1
    Views:
    411
    Joona I Palaste
    Aug 24, 2003
  3. Ben Finney
    Replies:
    2
    Views:
    979
    Egor Bolonev
    Jun 30, 2003
  4. Egor Bolonev
    Replies:
    0
    Views:
    470
    Egor Bolonev
    Jun 30, 2003
  5. Serge Terekhoff
    Replies:
    0
    Views:
    634
    Serge Terekhoff
    Jun 30, 2003
Loading...

Share This Page