Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / First Aid / July 2008

Tip: Looking for answers? Try searching our database.

imcompatible type when converting a List to array

Thread view: 
thufir - 19 Jun 2008 15:43 GMT
I have an ArrayList<Guest> which I want to convert to an Array, but I'm
getting:

init:
deps-jar:
Compiling 2 source files to /home/thufir/JavaProject28/build/classes
/home/thufir/bcit-comp2611-project2/src/a00720398/view/Tabs.java:15:
incompatible types
found   : java.lang.Object[]
required: a00720398.data.Guest[]
  Guest some_guests[] = FileUtil.getGuests().toArray();
1 error
BUILD FAILED (total time: 6 seconds)

If I change it to:

Object some_guests[] = FileUtil.getGuests().toArray();

then it works fine, but that's rather absurd because I know that the type
is Guest so I don't see why it would have to be an array of Object.

Surely I don't have to cast to Guest?

thanks,

Thufir
Nigel Wade - 19 Jun 2008 16:48 GMT
> I have an ArrayList<Guest> which I want to convert to an Array, but I'm
> getting:
[quoted text clipped - 22 lines]
>
> Thufir

There's another method which does what you want. It's a bit of a "hack", but it
does allow you to get an array of the correct type.

ArrayList implements Collection, and Collection has two toArray() methods. The
second method:
<T> T[] toArray(T[] a);
allows you to pass an array of type T as parameter, and it will return an array
of the same type. If the array passed is large enough it will put the contents
into that array, otherwise it creates a new array sufficient to hold the
contents. The "hack" is to pass an array of size 0:

Guest some_guests[] = FileUtil.getGuests().toArray(new Guest[0]);

Signature

Nigel Wade

Lew - 19 Jun 2008 18:57 GMT
> I have an ArrayList<Guest> which I want to convert to an Array, but I'm
> getting:
[quoted text clipped - 6 lines]
> required: a00720398.data.Guest[]
>    Guest some_guests[] = FileUtil.getGuests().toArray();

The idiom
   Guest [] someGuests = ...
is superior, both because the notation "Guest []" is a closer analog
to the English version, "array of Guest", and because the variable
name no longer violates the Java coding conventions.
<http://java.sun.com/docs/codeconv/index.html>
The other way would be pronounced, Yoda-like, as "Guest some_guests an
array of is, hmm", which is awkward.

> 1 error
> BUILD FAILED (total time: 6 seconds)
[quoted text clipped - 7 lines]
>
> Surely I don't have to cast to Guest?

Surely you do!

Were you to read the Javadocs for List#toArray()
<http://java.sun.com/javase/6/docs/api/java/util/List.html#toArray()>
something you should *always* do for API methods that don't behave the
way you expect, and frequently for those that do, you would discover
that the return type of the method is Object [].  So yeah, if you want
to do a narrowing conversion to Guest [] then you must cast.  Only
widening conversions don't require a cast.

Reading the Javadocs is the first line of attack to understand bugs.
It's incredibly useful.

As a side benefit, were you to read the Javadocs for List#toArray()
you likely would also notice the Javadocs for the overload
List#toArray(T[] a).
<http://java.sun.com/javase/6/docs/api/java/util/
List.html#toArray(T[])>
Once again the Javadocs can rescue you, leading you to the idiom

 Guest [] someGuests = FileUtil.getGuests().toArray( new Guest
[0] );

Always read the Javadocs.  Always read the Javadocs.  Always read the
Javadocs.

--
Lew
thufir - 19 Jun 2008 20:14 GMT
> As a side benefit, were you to read the Javadocs for List#toArray() you
> likely would also notice the Javadocs for the overload List#toArray(T[]
[quoted text clipped - 5 lines]
>   Guest [] someGuests = FileUtil.getGuests().toArray( new Guest
> [0] );

Thanks.  This isn't the first time I've run across that idiom (?) of the
zero length array anonymous reference, but I can't recall where else it
was...

I read the API and was aware of the overloaded method, just didn't know
if it was what I was after.

-Thufir
thufir - 19 Jun 2008 20:37 GMT
> I have an ArrayList<Guest> which I want to convert to an Array

Ok, I have JList which holds an array of Guests.  My plan was to have the
JList reference a Collection elsewhere, but now that there's an array of
Guests, then I might as well continue to work from the array directly.

For instance, create a listener so that when an element of the array is
clicked the Guest is displayed and available for CRUD type operations.

On the one hand, I want to separate the data (the model, the array of
Guests) from the view (the GUI).  Yes?

On the other hand, I just want to get it done.

It seems kinda awkward to have the array within the applications GUI
interface.  Any pointers?

thanks,

Thufir
Mark Space - 19 Jun 2008 22:35 GMT
> It seems kinda awkward to have the array within the applications GUI
> interface.  Any pointers?

It does, but it's also OK.  You're making the connection at runtime,
which is loose enough to still have good separation between the model
and the view.  As long as the model and view are communicating through
public access methods, you likely have plenty of separation between the two.

There's a quick object you can use for an arbitrary interface between
the view proper and the model, AbstractListModel.  That's a special
model that already know how to talk to a JList, you just supply the
actual data.

"Just getting it done" is OK, just at least know that ALM is available.
Roedy Green - 20 Jun 2008 01:09 GMT
>Object some_guests[] = FileUtil.getGuests().toArray();

Don't use the lazy form of toArray.  When you use the long form you
get an array of the proper type and size created without reflection.
You won't need any casts.

You are violating conventions.  Put the [] next to the type.  The old
C form just confuses people.

variables must begin with a lower case letter.

so that would become something like this::

Collection<Guest> guests = fileUtility.getGuests();
Guest[] someGuests = guests.toArray ( new Guest[ guests.size() ]);
Signature


Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Daniel Pitts - 20 Jun 2008 01:45 GMT
> I have an ArrayList<Guest> which I want to convert to an Array, but I'm
> getting:
[quoted text clipped - 13 lines]
>
> Object some_guests[] = FileUtil.getGuests().toArray();
Just a note, c++ programmers use "Foo foos[];" Java programmers use
"Foo[] foos;"  Not a big deal, but it will throw/put some people off.

> then it works fine, but that's rather absurd because I know that the type
> is Guest so I don't see why it would have to be an array of Object.
[quoted text clipped - 4 lines]
>
> Thufir
Why use an array at all, instead of using the List<Guest> returned by
FileUtil directly?  Arrays are /almost/ always the wrong abstraction to
hold Objects.

If you insist on using a Guest array, you can use
Guest[] some_guests = FileUtil.getGuests().toArray(new Guest[0]);

Hope this helps,
Daniel.

Signature

Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>

Thufir - 20 Jun 2008 03:36 GMT
On Jun 19, 5:45 pm, Daniel Pitts
[...]
> Why use an array at all, instead of using the List<Guest> returned by
> FileUtil directly?  Arrays are /almost/ always the wrong abstraction to
> hold Objects.
>
> If you insist on using a Guest array, you can use
> Guest[] some_guests = FileUtil.getGuests().toArray(new Guest[0]);
[...]

Yes, absolutely I concur, but I'm just not sure how because the JList
seems to want an array...I'll RTFM on that.

If it's possible to use the List<Guest> returned by FileUtil, then I
can perform my CRUD operations through FileUtil :)

-Thufir
Daniel Pitts - 20 Jun 2008 05:01 GMT
> On Jun 19, 5:45 pm, Daniel Pitts
> [...]
[quoted text clipped - 13 lines]
>
> -Thufir
Think about creating your own ListModel implementation that wraps your
List<Guest> object.

Signature

Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>

Thufir - 20 Jun 2008 08:51 GMT
On Jun 19, 9:01 pm, Daniel Pitts
<newsgroup.spamfil...@virtualinfinity.net> wrote:
> > On Jun 19, 5:45 pm, Daniel Pitts
> > [...]
[quoted text clipped - 19 lines]
> --
> Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>

What I have so far is the static method FileUtils.loadGuests() returns
a DefaultListModel, which seems sufficient for my needs, and then I'm
thinking that if there's a change to then pass the DefaultListModel
back to, for instance, FileUtils.writeGuests(DefaultListModel guests)
to write to disc.

Then, I suppose the GUI should call FileUtils.loadGuests() again to
sync it.

seems a bit odd, but I guess that's reasonable.

-Thufir
Lew - 20 Jun 2008 14:46 GMT
> What I have so far is the static method FileUtils.loadGuests() returns
> a DefaultListModel, which seems sufficient for my needs, and then I'm

That breaks the separation between model and view.

Better is to have a custom ListModel as Daniel suggested.

class GuestListModel extends DefaultListModel
{
 private List<Guest> modelData;
...
}

Now FileUtils need know nothing about how its results will be displayed.
Otherwise, what if you decide you don't like Swing any more, or want to port
to JSF or GWT?  You would have to rewrite FileUtils.  Yecch.

Have FileUtils deal only with List<Guest>.  ListModel is the canonical
differential gear between model and view.

ListModel listModel = new GuestListModel( FileUtil.getGuests() );

Now we have clean separation and decoupled communication between model and view.

Signature

Lew

Thufir - 21 Jun 2008 04:14 GMT
[...]
> Now FileUtils need know nothing about how its results will be displayed.
> Otherwise, what if you decide you don't like Swing any more, or want to port
[quoted text clipped - 6 lines]
>
> Now we have clean separation and decoupled communication between model and view.

pardon, but I'm stuck in the details regarding GUI. How would this be
updated?

guestList.setModel(FileUtil.getGuests() /* kludge which returns a
DefaultListModel */);  //guestList is a JList

If I'm going to do that, then I would also want to make ListModel a
singleton along the lines of:

public class GuestListModel extends DefaultListModel
{

  private static final GuestListModel INSTANCE = new DataList();

  private List<Guest> guests; // = FileUtil.getGuests();

  private GuestListModel()
  {
     guests = FileUtil.getGuests();
  }

  public static GuestListModel getInstance()
  {return INSTANCE;}
}

thanks,

Thufir
Lew - 21 Jun 2008 04:24 GMT
Lew wrote:
>> ListModel listModel = new GuestListModel( FileUtil.getGuests() );
>>
>> Now we have clean separation and decoupled communication between model and view.

> pardon, but I'm stuck in the details regarding GUI. How would this be
> updated?

Of which "this" do you speak?  If you mean the GuestListModel, that would
depend on how you implement the class.  One way would be to keep a reference
to the ListModel and update it.

> guestList.setModel(FileUtil.getGuests() /* kludge which returns a
> DefaultListModel */);  //guestList is a JList

Is this the "this" of which you spoke?  But the snippet still has
FileUtil.getGuests() returning a ListModel, which breaks model-view
separation, i.e., it overlaps the two domains improperly.

> If I'm going to do that, then I would also want to make ListModel a
> singleton

Why?

Signature

Lew

Lew - 24 Jun 2008 20:08 GMT
Thufir wrote:
> > If I'm going to do that, then I would also
> > want to make ListModel a singleton

Lew wondered aloud:
> Why?

I really want to know.  What are the advantages you see to making it a
singleton, and disadvantages otherwise?

--
Lew
thufir - 28 Jun 2008 12:47 GMT
> I really want to know.  What are the advantages you see to making it a
> singleton, and disadvantages otherwise?

Ignoring the use of DefaultListModel for the purposes of this thread,
here's the model:

thufir@arrakis:~/bcit-comp2611-project2$
thufir@arrakis:~/bcit-comp2611-project2$ cat src/a00720398/data/
GuestsModel.java
package a00720398.data;

import javax.swing.*;
import a00720398.util.*;

@SuppressWarnings({"unchecked", "serial"})
public class GuestsModel extends DefaultListModel {

   private static final GuestsModel INSTANCE = new GuestsModel();

   private GuestsModel() {
       java.util.List<Guest> Guests = FileUtil.readGuests();
       for (Guest guest : Guests) {
           addElement(guest);
       }
   }

   public static GuestsModel getInstance() {
       return INSTANCE;
   }
}
thufir@arrakis:~/bcit-comp2611-project2$

By making it a Singleton it's impossible to accidentally have two "guest
lists" hanging around, by the definition of Singleton.  You wouldn't want
to accidentally have duplicate db tables, would you?  Plus, it was extra
points for making it a Singleton ;)

You couldn't accidentally re-read guests and wipe out the data, you'll
just get back INSTANCE.  Allegedly, the idea is to modify, in this case,
GuestsModel, and then any changes are supposed to be reflected in the
view.

Had I known x days ago that you could just call addElement() from the
constructor and ?implicitly? add objects to the instance, I would've
saved myself a huge headache.  Anyhow, now I know.

Out of curiosity, and on a tangent, if the model extends DefaultListModel
then what would the controller look like?  I have:

thufir@arrakis:~/bcit-comp2611-project2$
thufir@arrakis:~/bcit-comp2611-project2$ cat src/a00720398/data/
GuestsController.java
package a00720398.data;

import java.util.*;
import javax.swing.event.*;

   public class GuestsController implements ListSelectionListener,
Observer {

       public void update(Observable arg0, Object arg1) {
       // TODO Auto-generated method stub

       }

       public void valueChanged(ListSelectionEvent event) {
           //Object obj = guestsView.getSelectedValue();
           //Guest guest = (Guest) obj;
           //displayGuest(guest);
       }
   }thufir@arrakis:~/bcit-comp2611-project2$
thufir@arrakis:~/bcit-comp2611-project2$

The purpose of GuestsController is to sync the view with the model?

Controller
   Processes and responds to events, typically user actions, and may
invoke changes on the model.

http://en.wikipedia.org/wiki/Model-view-controller

-Thufir
thufir - 03 Jul 2008 09:44 GMT
> That breaks the separation between model and view.
>
[quoted text clipped - 4 lines]
> ...
> }

Why do you have a List in there?

public class GuestsModel extends DefaultListModel{

   private static final GuestsModel INSTANCE = new GuestsModel();

   private GuestsModel() {
       java.util.List<Guest> guests = FileUtil.deserializeList();

       for (Guest guest : guests) {
           addElement(guest);
       }
       //addAll(0,guests);
   }

   public static GuestsModel getInstance() {
       return INSTANCE;
   }
 
}

thanks,

Thufir
Lew - 20 Jun 2008 15:08 GMT
> What I have so far is the static method FileUtils.loadGuests()
> ... FileUtils.writeGuests(DefaultListModel guests)
> ... FileUtils.loadGuests()

Rely far, far less on static methods.  The burden of proof is on staticness to
justify itself, otherwise the bias should be to instanceness.

Signature

Lew

Roedy Green - 03 Jul 2008 23:11 GMT
>.toArray();

the short answer is toArray ( new specific[ size ] )
instead.

see http://mindprod.com/jgloss/arraylist.html
Signature


Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Roedy Green - 03 Jul 2008 23:12 GMT
>Object some_guests[] = FileUtil.getGuests().toArray();

this looks familiar.  I think I explained this before.
Signature


Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.