I am trying to make a program where I can add a name and it's supposed to be saved in a RandomAccessFile
, (alphabetically). Whenever I add a name it gets saved in a file, it's supposed to have at the end the next corresponding position for the next name. I'm having problems with the saving whenever I add a name with starting with A, then I add a name with C, and if I where to add a name starting with B it's not pointing me in the right alphabetical order.
Here is what an example of what the program should do:
I add a name starting with A.
Numbers on "left" side are just where the next name start, Numbers on "right" side are the pointers to the next name
[0]-----A----[-1] ----------- the "-1" pointer means its the end of the list
I add a name starting with C.
[0]-----A----[100] ------- the "100" pointer means that the next name "C" start on byte 100
[100]---C----[-1] --------- end of the list pointer, notice how A no longer has the "-1" pointer
I add a name starting with B.
[0]-----A----[200] ------ "A" no longer points to 100 because the next letter should be "B"
[100]---C----[-1] -------- -1 still means that "C" is the end of the list pointer
[200]---B----[100] --------- "B" is pointing at "C" because the next letter after
Here is my code so far, but I'm missing the part where a name that belongs in the middle of the list is added.
public boolean add(String name, String lastName, String telf) {
try {
fileSize = file.length();
} catch (IOException ex) {
ex.printStackTrace();
}
if (fileSize == 0) { //must be a new entry
try {
byte entry[] = new byte[sizeEntry]; // size of each entry
file.write(entry);
file.seek(file.getFilePointer() - sizeEntry);
file.writeUTF(name); //name gets saved
file.writeUTF(lastName);// last name gets saved
file.writeUTF(telf); // telf gets saved
file.writeUTF("N"); // deleted "Y" or "N" gets saved
file.writeUTF("-1"); // pointer gets saved
} catch (IOException e) {
System.out.println("Error at saving....");
e.printStackTrace();
}
} else {
pPresent= 0; //variable for the pointer reading
pPrevious= 0; // variable for the pointer read
try {
file.seek(0); //start reading at the top
do {
pPresent= file.getFilePointer();//saves present pointer
file.seek(pPresent);//seeks to present pointer
nameRead = file.readUTF(); //reads name
file.readUTF(); //reads last name
file.readUTF(); //reads telf
file.readUTF(); //reads deleted?
pNext= Long.parseLong(file.readUTF()); // reads the next pointer
int comparison= name.compareTo(nameRead);
if (comparison< 0) {
//enters here if the new entry goes before the present entry
if (pNext!= -1) {
file.seek(pNext);//enters here if pointer is not at end of list
} else {
try {// proceeds to writing a new entry
file.seek(file.length()); //goes to the end of the file
byte entry[] = new byte[sizeEntry];
file.write(entry);
file.seek(file.getFilePointer() - sizeEntry);
file.writeUTF(name);
file.writeUTF(lastname);
file.writeUTF(telf);
file.writeUTF("N");
file.writeUTF(Long.toString(pPrevious));//writes the previous pointer
file.seek(pPrevious);//seeks to the previous entry
file.readUTF();//reads name
file.readUTF();//reads lastname
file.readUTF();//reads telf
file.readUTF();//reads deleted?
file.writeUTF(Long.toString(pPrevious));//overwrites the new previous
} catch (IOException e) {
System.out.println("Error at saving...");
e.printStackTrace();
}
break;//exits
}
} else {//enteres here if the entry is bigger than the present
if (pNext!= -1) {
file.seek(pNext);
} else {
try {
pPresent= file.length()-sizeEntry;//saves present entry
file.seek(pPrevious); //seeks to previous entry
file.readUTF();//reads name
file.readUTF();//reads last name
file.readUTF();//reads telf
file.readUTF();//reads deleted
file.writeUTF(Long.toString(pPresent+100));//overwrites the next pointer
file.seek(file.length());//seeks at the end
byte entry[] = new byte[sizeEntry];//creates a new entry
file.write(entry);
file.seek(file.getFilePointer() - sizeEntry);
file.writeUTF(name);//writes name
file.writeUTF(lastname);//writes lastname
file.writeUTF(telf);//writes telf
file.writeUTF("N");//writes deleted
file.writeUTF(Long.toString(pNext));//writes next pointer
} catch (IOException e) {
System.out.println("Error at saving...");
e.printStackTrace();
}
break;//exits
}
}
pPresent= file.getFilePointer();//present pointer read
pPrevious= pPresent;//present pointer becomes previous
} while (true);
} catch (IOException e) {
System.out.println("Error at saving....");
e.printStackTrace();
}
}
return false;
}
I hope you guys understand the idea of the program a little better now with the source code. The part I don't know how to do is where I add a entry that belongs in the middle of the list. Remember that the order of the names dont change only the pointers pointing to the next do.
Finding the insertion point will require traversing the list, which in turn requires a disk access for every single name. Assuming you have 1 million names, and a typical disk access time of 10 ms, inserting a single name would take about 3 hours. Put differently, linked lists are an extremly unsuitable data structure for storing data on disk.
A reasonable data structure such as a B-Tree would permit lookup and insertion among 1 million names in as little as 3 disk accesses.