Now I am creating an address book in Java 1.6. Now how I have it set up is when you add a contact it gets saved into an array. I have no problem writing the array, however when it comes to reading it I dont know how to get every object I previously saved, and load it into the array again.
Just do you know: addbook is my file, it is a txt file. Array is the array I am using to store the objects. The sort I am using is an insertion sort that sorts the contacts by name. If I have not covered other variable names, and stuff like that, I can clarify.
Finally, just for clarification, my question is asking how I can read the array I saved to a file.
Here is my read code:
try {
FileInputStream in = new FileInputStream(addBook);
ObjectInputStream readIn = new ObjectInputStream(in);
array = readIn.readObject();
readIn.close();
Sorts.insertionSort(array);
model.removeAllElements();
for (int i = array.length - 1; i > 0; i--) {
model.addElement(((Book) array[i]).getContact());
}
comboBox.setModel(model);
} catch (Exception e) {
e.printStackTrace();
}
ObjectInputStream.readObject returns an Object. You cannot assign an Object to a Comparable[] without a cast: array = (Comparable[]) readIn.readObject().
Related
I seem to be having an issue with not properly syntaxing my code, but as I've just started out with learning I seem to be missing the error. It's a homework assignment, where I need to use an Array of JxploreFile-objects. This is the part of the code I'm having trouble with:
private JxploreFile[] getSubFolders()
{
File subFiles[];
subFiles = file.listFiles();
File subFolders[];
int p = 0;
for(int i = 0; i < subFiles.length; i++)
{
if(subFiles[i].isDirectory() == true)
{
Array.set(subFolders, p, subFiles[i]);
}
}
JxploreFile foldersToReturn[] = new JxploreFile[subFolders.length];
for(int i=0; i < subFolders.length; i++)
{
foldersToReturn[i] = new JxploreFile(subFolders[i]);
}
return foldersToReturn;
}
Specifically, the for-loop where I'm trying to add the files marked as .isDirectory into a new Array. I've also tried other methods by placing each new file coming from the subFiles Array manually into the subFolders Array by declaring indexnumbers, but this also turned out faulty. At this point I'm out of ideas and I hope there is someone who can point me out the obvious, as I'm probably missing something reallly basic.
Edit:
I'm sorry for the incomplete post, It's the first time I actually post here as I usually try to filter my own problems out of the posts of others. The error I got was indeed that 'subFolders' had not been initialized yet, which I didn't understood because on the sixth line I wrote
File subFolders[];
which as far as I know should declare the variable subFolders to become an Array, or is this where I went wrong?
Also, my question might not have been specific enough, I'm looking for what causes the error (which I didn't mention at all): why 'subFiles' wasn't initialized.
The array subFolders has not been initialized properly. In order to use the array in the Array.set method it must be initialized and allocated with a size.
An alternative approach for this is to use a List instead. Lists are good when you are working with data that is more dynamic e.g. when you do not know the size of the array. Then you can simplify your code like this:
File[] subFiles = file.listFiles();
// Create the list
List<JxploreFile> subFolders = new ArrayList<>();
// Add all the sub folders (note that "file" is a bit magic since it
// is not specified anywhere in the original post
for (File subFile : file.listFiles()) {
if (subFile.isDirectory()) {
subFolders.add(new JxploreFile(subFile));
}
}
// Return an array
return subFolders.toArray(new JxploreFile[subFolders.size()]);
You can also simplify the whole thing even further by using a Java 8 stream like this:
return Arrays.stream(file.listFiles())
.filter(File::isDirectory)
.toArray(JxploreFile[]::new);
For more info:
Creating Objects in Java
Arrays
There is no question in your post, but anyway here the problems I found in your code :
File subFolders[];
int p = 0;
for(int i = 0; i < subFiles.length; i++)
{
if(subFiles[i].isDirectory() == true)
{
Array.set(subFolders, p, subFiles[i]);
}
}
when calling Array.set you never initialized subFolders which will throw a NullPointerException.
Also, you dont need to do
if(subFiles[i].isDirectory() == true)
you can simply do
if(subFiles[i].isDirectory())
as subFiles[i].isDirectory() is already a condition.
In my program users input words along with their corresponding definition.
An example of this user defined object is [countenance, a person's face].
The user's words are stored in an array list which works with file i/o.
However, each time I call the "prepareTable" method, the program
adds duplicates of the words found in the text file to the array list. If you need to see more code, I can post it but for convenience/readability I only posted the prepareTable method. Why is my program duplicating the words? Is there something wrong with this method?
public void prepareTable ()
{
readFromFile();
for (int i = 0; i <= LibraryWordsList.size() - 1; i++)
{
tableData.setValueAt(LibraryWordsList.get(i).getWord(), i, 0);
tableData.setValueAt(LibraryWordsList.get(i).getDefinition(), i, 1);
}
}
If tableData refers to an instance of DefaultTableModel, you can invoke setRowCount(0) to clear the previous entries before adding new ones. You can get a reference to the table's TableModel by using the table's getModel() method.
im currently working on a multiple class assignment where i have to add a course based on whether the prerequisites exist within the program.
im storing my courses within the program class using a hashmap. (thought i would come in handy) however, im having a bit of trouble ensuring that these preReqs exist.
here is some code ive currently got going
public boolean checkForCourseFeasiblity(AbstractCourse c) throws ProgramException
{
AbstractCourse[] tempArray = new AbstractCourse[0];
tempArray= courses.keySet().toArray(tempArray);
String[] preReqsArray = new String[1];
preReqsArray = c.getPreReqs();
//gets all course values and stores them in tempArray
for(int i = 0; i < preReqsArray.length; i++)
{
if(courses.containsKey(preReqsArray[i]))
{
continue;
}
else if (!courses.containsKey(preReqsArray[i]))
{
throw new ProgramException("preReqs do not exist"); //?
}
}
return true;
}
ok so basically, tempArray is storing all the keySets inside the courses hashmap and i need to compare all of them with the preReqs (which is an array of Strings). if the preReqs exist within the keyset then add the course, if they dont do not add the course. return true if the course adds otherwise through me an exception. keep in mind my keysets are Strings e.g. a keyset value could be "Programming1" and the required prerquisite for a course could be "programming1". if this is the case add then add the course as the prereq course exists in the keyset.
i believe my error to be when i initialize mypreReqsArray with c.getPreReqs (note: getPreReqs is a getter with a return type String[]).
it would be really great if someone could aid me with my dilemma. ive tried to provide as much as possible, i feel like ive been going around in circles for the past 3 hours :(
-Thank you.
Try something like this, you don't need tempArray. The "for each" loop looks lots nicer too. If you want to throw an Exception I would put that logic in the place that calls this method.
public boolean checkForCourseFeasiblity(AbstractCourse c)
{
for(String each : c.getPreReqs())
{
if(! courses.containsKey(each))
{
return false;
}
}
return true;
}
friends,
i am facing a problem i have phoneContacts list with name and phone numbers in it.
i want to copy it in two different static lists so that i can use it to other activities. i am using following code but it displays me last list references in both while retrieving data
any one guide me how can i take separate copies of these two objects ?
MyContacts.attackContacts = new ArrayList(phoneContacts);
Collections.copy(MyContacts.attackContacts,phoneContacts);
MyContacts.attackContacts.get(0).setType("attack");
MyContacts.medicalContacts = new ArrayList(phoneContacts);
Collections.copy(MyContacts.medicalContacts,phoneContacts);
MyContacts.medicalContacts.get(0).setType("medical");
System.out.println("attack" + MyContacts.attackContacts.get(0).getType() + " medical " + MyContacts.medicalContacts.get(0).getType());
// result "attack medical" "medical medical"
// it should show independent list results like "attack attack" "medical medical"
any help would be appreciated.
In this case you would need to make a deep copy of the list, i.e., a copy that doesn't copy references, but actually copies the object the references are pointing at.
Collections.copy "copies all of the elements from one list into another". As usual with Java however, the elements of a list are not objects but references.
You could solve this by implementing Cloneable (and using .clone()) or by creating a custom "copy constructor" which takes a to-be-copied object as argument, and creates a new object based on the data of that argument. No matter which option you choose, you'll have to iterate over the list and perform the copy on each object.
Here's an example that uses the copy-constructor approach:
MyContacts.medicalContacts = new ArrayList();
for (Contact c: MyContacts.attackContacts)
medicalContacts.add(new Contact(c)); // add a copy of c.
Related question:
What is the difference between a deep copy and a shallow copy?
Coping the list, creates new list object that still refers to the same element objects.
To make a deep copy, your element object must be clonable, have copy constructor, or some other way to duplicate it and you have to do the copy in a loop, one by one.
for (Elem x: list1) {
list2.add(copyOf(x))
}
Pass the object whcih you wants to copy and get the object which you wants ,
private Object copyObject(Object objSource) {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(objSource);
oos.flush();
oos.close();
bos.close();
byte[] byteData = bos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(byteData);
try {
objDest = new ObjectInputStream(bais).readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
return objDest;
}
Cast you objDest to Desiered object
this is my code snippet.
data is a 2D array of type Object.I have previously saved data in JTable.Now i have written
code to delete entry.But if go by this code only first entry gets deleted from JTable.
I am unable to understand the reason behind this.
please help me out in this.
-snippet:
public void deleteActionPerformed(ActionEvent ae) {
String delname=tf4.getText();
int c=0;
try {
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("data.txt"));
data=(Object[][])ois.readObject();
for(;;c++) {
String x=(String)data[c][0];
if(x.equals(delname)) {
System.out.println("if working");
data[c][0]=null;
data[c][1]=null;
data[c][2]=null;
try {
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("data.txt"));
oos.writeObject(data);
} catch(Exception exc) {
System.out.println("error deleting data from"+" "+c+" row");
}
c++;
JOptionPane.showMessageDialog(new JFrame(),"contact deleted");
try {
ObjectInputStream oist=new ObjectInputStream(new FileInputStream("data.txt"));
data=(Object[][])oist.readObject();
JTable tb=new JTable(data,headers);
ObjectOutputStream oost=new ObjectOutputStream(new FileOutputStream("contacts.txt"));
oost.writeObject(tb);
} catch(Exception exc) {
System.out.println("error updating after deleting");
}
}
else
System.out.println("else working");
}
} catch(Exception exc) {
System.out.println("error reading data.txt for deleting");
}
}
After properly indenting your code, it becomes more obvious ...
You are re-creating (and re-reading) the file in your loop, instead of after it - why?
You are writing out a new JTable object after every deletion.
Why writing it out at all?
How are you reading them?
Additionally, you have two c++ inside your loop, so the second element of the array is skipped.
Third, in case of exceptions you simply go on (and even don't print out the whole exception).
You can only run this algorithm to delete once before getting a NullPointerException
If in a previous run you deleted any item, you'll get a NPE each time you compare it.
String x=(String)data[c][0];
if(x.equals(delname)) {
It would be safer if you do delname.equals(x) (assuming you have checked that delname is not null before) or check for x == null in the if before equals.
A better solution would be, after the loop, copying the array to a new one without the deleted elements. Even better, after deserializing the object, pass it to a List class and work with it, and only pass it back to array in order to serialize it when you are finished with the program (or directly serialize the List, if you can).
That said, I cannot find anything that would work with the first element but not the others. Maybe it is that when you run your test you first try with the first element and then, after corrupting the array so you'll have a NPE, you test the other elements.
EDIT: Didn't see the extra c++ (probably it was a while before?). Only will work with odd element indexes.