Java Forum / First Aid / July 2008
imcompatible type when converting a List to array
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 MagazinesGet 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 ...
|
|
|