I have a problem with maing java reading a file for me. I have a .txt-file with all the danish islands but somehow it will not display in the console no matter how i try.
This is the class with the main method. From here it reads the file and splits the lines in order to put the data into an ArrayList.
public class DanishIslandFileReader {
private File inFile;
private List<DanishIsland> islandList;
public DanishIslandFileReader(String fName) {
inFile = new File(fName);
}
private void readFile() {
islandList = new ArrayList<DanishIsland>();
Scanner scan = null;
try {
scan = new Scanner(inFile);
} catch (FileNotFoundException fnfe) {
System.out.println(fnfe);
}
while (scan.hasNext()) {
String line = scan.nextLine();
String[] tokens = line.split(" ");
String name = tokens[0];
double circ = Double.parseDouble(tokens[1]);
double area = Double.parseDouble(tokens[2]);
int addr = Integer.parseInt(tokens[3]);
int adkm = Integer.parseInt(tokens[4]);
DanishIsland island = new DanishIsland(name, circ, area, addr, adkm);
System.out.println(island.toString());
islandList.add(island);
}
scan.close();
}
public List<?> getList() {
return islandList;
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws FileNotFoundException {
System.out.println(new File(".").getAbsolutePath());
// DanishIslandFileReader fr = new DanishIslandFileReader("Islands punktum.txt");
DanishIslandFileReader fr = new DanishIslandFileReader("Islands komma.txt");
fr.readFile();
System.out.println("Result:\n" + fr.getList());
}
}
When the line has been split it goes through another class which turns the data into a String and puts it into another Arraylist which will be printed in the consol.
public class DanishIsland {
private String name;
private double circumference;
private double area;
private int addresses;
private int addrPerKm2;
public DanishIsland(String name, double circumference, double area,
int addresses, int addrPerKm2) {
super();
this.name = name;
this.circumference = circumference;
this.area = area;
this.addresses = addresses;
this.addrPerKm2 = addrPerKm2;
}
public String getName() {
return name;
}
public double getCircumference() {
return circumference;
}
public double getArea() {
return area;
}
public int getAddresses() {
return addresses;
}
public int getAddrPerKm2() {
return addrPerKm2;
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(name);
builder.append("\t");
builder.append(circumference);
builder.append("\t");
builder.append(area);
builder.append("\t");
builder.append(addresses);
builder.append("\t");
builder.append(addrPerKm2);
builder.append("\n");
return builder.toString();
}
}
I do not get any errors or exceptions and the program run till it thinks the list has been printed.
Problem is that the list is empty and I can't seem to make any sort of "sout" from the .txt-file. Whar am I doing wrong?
Lolland 298,388 1234,96 38919 32
Bornholm 108,047 588,025 27125 46
Falster 145,926 516,268 26654 52
Mors 139,254 361,745 12374 34
Have you tried debugging it?
I think it is not entering
while (scan.hasNext())
because scan.hasNext returns false.
This could be a file permission issue.
Also this may be related:
Why is hasNext() False, but hasNextLine() is True?
Related
I have this textfile which I like to sort based on HC from the pair HC and P3
This is my file to be sorted (avgGen.txt):
7686.88,HC
20169.22,P3
7820.86,HC
19686.34,P3
6805.62,HC
17933.10,P3
Then my desired output into a new textfile (output.txt) is:
6805.62,HC
17933.10,P3
7686.88,HC
20169.22,P3
7820.86,HC
19686.34,P3
How can I sort the pairs HC and P3 from textfile where HC always appear for odd numbered index and P3 appear for even numbered index but I want the sorting to be ascending based on the HC value?
This is my code:
public class SortTest {
public static void main (String[] args) throws IOException{
ArrayList<Double> rows = new ArrayList<Double>();
ArrayList<String> convertString = new ArrayList<String>();
BufferedReader reader = new BufferedReader(new FileReader("avgGen.txt"));
String s;
while((s = reader.readLine())!=null){
String[] data = s.split(",");
double avg = Double.parseDouble(data[0]);
rows.add(avg);
}
Collections.sort(rows);
for (Double toStr : rows){
convertString.add(String.valueOf(toStr));
}
FileWriter writer = new FileWriter("output.txt");
for(String cur: convertString)
writer.write(cur +"\n");
reader.close();
writer.close();
}
}
Please help.
When you read from the input file, you essentially discarded the string values. You need to retain those string values and associate them with their corresponding double values for your purpose.
You can
wrap the double value and the string value into a class,
create the list using that class instead of the double value alone
Then sort the list based on the double value of the class using either a Comparator or make the class implement Comparable interface.
Print out both the double value and its associated string value, which are encapsulated within a class
Below is an example:
static class Item {
String str;
Double value;
public Item(String str, Double value) {
this.str = str;
this.value = value;
}
}
public static void main (String[] args) throws IOException {
ArrayList<Item> rows = new ArrayList<Item>();
BufferedReader reader = new BufferedReader(new FileReader("avgGen.txt"));
String s;
while((s = reader.readLine())!=null){
String[] data = s.split(",");
double avg = Double.parseDouble(data[0]);
rows.add(new Item(data[1], avg));
}
Collections.sort(rows, new Comparator<Item>() {
public int compare(Item o1, Item o2) {
if (o1.value < o2.value) {
return -1;
} else if (o1.value > o2.value) {
return 1;
}
return 0;
}
});
FileWriter writer = new FileWriter("output.txt");
for(Item cur: rows)
writer.write(cur.value + "," + cur.str + "\n");
reader.close();
writer.close();
}
When your program reads lines from the input file, it splits each line, stores the double portion, and discards the rest. This is because only data[0] is used, while data[1] is not part of any expression.
There are several ways of fixing this. One is to create an array of objects that have the double value and the whole string:
class StringWithSortKey {
public final double key;
public final String str;
public StringWithSortKey(String s) {
String[] data = s.split(",");
key = Double.parseDouble(data[0]);
str = s;
}
}
Create a list of objects of this class, sort them using a custom comparator or by implementing Comparable<StringWithSortKey> interface, and write out str members of sorted objects into the output file.
Define a Pojo or bean representing an well defined/organized/structured data type in the file:
class Pojo implements Comparable<Pojo> {
private double value;
private String name;
#Override
public String toString() {
return "Pojo [value=" + value + ", name=" + name + "]";
}
public double getValue() {
return value;
}
public void setValue(double value) {
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* #param value
* #param name
*/
public Pojo(double value, String name) {
this.value = value;
this.name = name;
}
#Override
public int compareTo(Pojo o) {
return ((Double) this.value).compareTo(o.value);
}
}
then after that: read->sort->store:
public static void main(String[] args) throws IOException {
List<Pojo> pojoList = new ArrayList<>();
BufferedReader reader = new BufferedReader(new FileReader("chat.txt"));
String s;
String[] data;
while ((s = reader.readLine()) != null) {
data = s.split(",");
pojoList.add(new Pojo(Double.parseDouble(data[0]), data[1]));
}
Collections.sort(pojoList);
FileWriter writer = new FileWriter("output.txt");
for (Pojo cur : pojoList)
writer.write(cur.toString() + "\n");
reader.close();
writer.close();
}
Using java-8, there is an easy way of performing this.
public static void main(String[] args) throws IOException {
List<String> lines =
Files.lines(Paths.get("D:\\avgGen.txt"))
.sorted((a, b) -> Integer.compare(Integer.parseInt(a.substring(0,a.indexOf('.'))), Integer.parseInt(b.substring(0,b.indexOf('.')))))
.collect(Collectors.toList());
Files.write(Paths.get("D:\\newFile.txt"), lines);
}
Even better, using a Method reference
public static void main(String[] args) throws IOException {
Files.write(Paths.get("D:\\newFile.txt"),
Files.lines(Paths.get("D:\\avgGen.txt"))
.sorted(Test::compareTheStrings)
.collect(Collectors.toList()));
}
public static int compareTheStrings(String a, String b) {
return Integer.compare(Integer.parseInt(a.substring(0,a.indexOf('.'))), Integer.parseInt(b.substring(0,b.indexOf('.'))));
}
By using double loop sort the items
then just comapre it using the loop and right in the sorted order
public static void main(String[] args) throws IOException {
ArrayList<Double> rows = new ArrayList<Double>();
ArrayList<String> convertString = new ArrayList<String>();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("C:/Temp/AvgGen.txt"));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String s;
try {
while((s = reader.readLine())!=null){
String[] data = s.split(",");
convertString.add(s);
double avg = Double.parseDouble(data[0]);
rows.add(avg);
}
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
FileWriter writer = new FileWriter("C:/Temp/output.txt");;
Collections.sort(rows);
for (double sorted : rows) {
for (String value : convertString) {
if(Double.parseDouble(value.split(",")[0])==sorted)
{
writer.write(value +"\n");
}
}
}
I am creating three classes,
First, ExchangeRate class for storing the data from the text file.
code public class ExchangeRate {
private String Local;
private String Foreign;
private double Rate;
public ExchangeRate(String Px, String Py, double ER) {
Local = Px;
Foreign = Py;
Rate = ER;
}
public void setLocal(String L) {
Local = L;
}
public void setForeign(String F) {
Foreign = F;
}
public void setRate(double R) {
Rate = R;
}
public String getLocal() {
return Local;
}
public String getForeign() {
return Foreign;
}
public double getRate() {
return Rate;
}
}
Then, I creat the CurrencyExchange class for converting the exchange rate which get from the constructor.
enter code here public class CurrencyExchange {
public int ratesize = 0;
public ExchangeRate[] allrecord = new ExchangeRate[42];
private String name1;
private String name2;
private double num;
private double num2;
public void convert(String currencyCode1, String currencyCode2,
double amount, boolean printFlag) {
name1 = currencyCode1;
name2 = currencyCode2;
num = amount; //change getLocal() to static?
if (name1 == ExchangeRate.getLocal()
&& name2 == ExchangeRate.getForeign()) {
num2 = num * ExchangeRate.getRate();
}
if (printFlag == true) {
printInfo();
}
}
public void addExchangeRate(ExchangeRate exRate) {
allrecord[ratesize] = exRate;
setratesize();
}
public void setratesize() {
ratesize++;
}
public String getname1() {
return name1;
}
public String getname2() {
return name2;
}
public double getnum() {
return num;
}
public void printInfo() {
System.out.println("Direct Conversion: Converted " + name1 + " " + num
+ " to " + name2 + " "+num2);
}
}
But I have diffculty on how to check if the currenncy can convert accroding to the name of the country indicate on the texting class, such as 'eur' and 'jpy. means convert EUR to JPT according to the exchange rate on the text.file. If I change that checking part
"If(name1==ExchangeRate.getLocal()" to static, Local will become the last data from the text.It cannot be checked. Therefore, I want to know How can I solve the problem?
Testing class
enter code here import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class MP2_Task1 {
public static void main(String[] args) {
CurrencyExchange currencyExchange = new CurrencyExchange();
String fileName = "exchange_rate.txt";
Scanner in = null;
try { // start reading data file
in = new Scanner(new File(fileName));
while (in.hasNextLine()) {
String line = in.nextLine();
String token[] = line.split(",");
if (token.length == 3) {
// create ExchangeRate instance for storing the exchange
// rate record
ExchangeRate exRate = new ExchangeRate(token[0], token[1],
Double.parseDouble(token[2]));
// adding the new exchange rate record to the
// CurrencyExchange instance
currencyExchange.addExchangeRate(exRate);
}
}
} catch (FileNotFoundException e) {
System.out.println(fileName + " cannot be found!");
} finally {
if (in != null) {
in.close();
}
}
String hkd = "HKD";
String usd = "USD";
String jpy = "JPY";
String gbp = "GBP";
String cny = "CNY";
String eur = "EUR";
String chf = "CHF";
// Task 1 - Simple money conversions
double oriAmount1 = 1000;
currencyExchange.convert(hkd, gbp, oriAmount1, true);
double oriAmount2 = 55;
currencyExchange.convert(cny, usd, oriAmount2, true);
double oriAmount3 = 300;
currencyExchange.convert(eur, jpy, oriAmount3, true);
double oriAmount4 = 8000;
currencyExchange.convert(hkd, chf, oriAmount4, true);
System.out.println();
}
}
Expected Output:
Direct Conversion: Converted HKD 1000.0 to GBP 83.8
Direct Conversion: Converted CNY 55.0 to USD 8.6735
Direct Conversion: Converted EUR 300.0 to JPY 39739.23
Direct Conversion: Converted HKD 8000.0 to CHF 1026.4
The whole text.file about exchange rate
HKD,USD,1.290000e-01
HKD,JPY,1.569860e+01
HKD,GBP,8.380000e-02
HKD,CNY,8.178000e-01
HKD,EUR,1.185000e-01
HKD,CHF,1.283000e-01
USD,HKD,7.750800e+00
USD,JPY,1.216885e+02
USD,GBP,6.499000e-01
USD,CNY,6.342400e+00
USD,EUR,9.187000e-01
USD,CHF,9.951000e-01
JPY,HKD,6.370000e-02
JPY,USD,8.200000e-03
JPY,GBP,5.300000e-03
JPY,CNY,5.210000e-02
JPY,EUR,7.500000e-03
JPY,CHF,8.200000e-03
GBP,HKD,1.192560e+01
GBP,USD,1.538600e+00
GBP,JPY,1.872341e+02
GBP,CNY,9.758600e+00
GBP,EUR,1.413500e+00
GBP,CHF,1.531000e+00
CNY,HKD,1.222100e+00
CNY,USD,1.577000e-01
CNY,JPY,1.918650e+01
CNY,GBP,1.025000e-01
CNY,EUR,1.448000e-01
CNY,CHF,1.569000e-01
EUR,HKD,8.437100e+00
EUR,USD,1.088600e+00
EUR,JPY,1.324641e+02
EUR,GBP,7.075000e-01
EUR,CNY,6.904000e+00
EUR,CHF,1.083100e+00
CHF,HKD,7.789700e+00
CHF,USD,1.005000e+00
CHF,JPY,1.222988e+02
CHF,GBP,6.532000e-01
CHF,CNY,6.374200e+00
CHF,EUR,9.233000e-01
if (name1.equals(ExchangeRate.getLocal())
&& name2.equals(ExchangeRate.getForeign())) {
num2 = num * ExchangeRate.getRate();
}
with == you compare the object references and not the values.
Here are my program's methods:
package ItPatPackage;
//Defines a banking Client
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.JOptionPane;
public class Client
{
//attributes
private String clientName;
private String clientPass;
private int accountNum;
private double currentBal;
private double savingsBal;
private boolean verify;
//default constructor
public Client()
{
clientName = "";
clientPass = "";
accountNum = 0;
currentBal = 0.0;
savingsBal = 0.0;
verify = false;
}
//parameterised constructor
private Client(String username,String password,int accNum, double
curBal,double savBal, boolean ver)
{
clientName = username;
clientPass = password;
accountNum = accNum;
currentBal = curBal;
savingsBal = savBal;
verify = ver;
}
//get methods
public String getClientName()
{
return clientName;
}
public String getClientPass()
{
return clientPass;
}
public int getAccNum()
{
return accountNum;
}
public double getCurrentBal()
{
return currentBal;
}
public double getSavingsBal()
{
return savingsBal;
}
public boolean getClientVerify()
{
return verify;
}
//mutator methods
public void setClientName(String username)
{
clientName= username;
}
public void setClientPass(String password)
{
clientPass = password;
}
//deposit
public void depositSavings(double ds)
{
savingsBal = savingsBal + ds;
}
public void depositCurrent(double dc)
{
currentBal = currentBal + dc;
}
//withdraw
public void withdrawSavings(double ws)
{
if (ws<savingsBal){
savingsBal = savingsBal - ws;
}
else{
JOptionPane.showMessageDialog(null, "Insufficient Funds.
\nYour Savings Balance is: R" + savingsBal);
}
}
public void withdrawCurrent(double wc)
{
if (wc<currentBal){
currentBal = currentBal - wc;
}
else{
JOptionPane.showMessageDialog(null, "Insufficient Funds.
\nYour Current Balance is: R" + currentBal);
}
}
//transfer
public void transferStoC(double sc)
{
if (sc<savingsBal){
savingsBal = savingsBal - sc;
currentBal = savingsBal + sc;
}
else{
JOptionPane.showMessageDialog(null, "Insufficient Funds.
\nYour Savings Balance is: R" + savingsBal);
}
}
public void transferCtoS(double cs)
{
if (cs<savingsBal){
savingsBal = savingsBal + cs;
currentBal = savingsBal - cs;
}
else{
JOptionPane.showMessageDialog(null, "Insufficient Funds.
\nYour Current Balance is: R" + currentBal);
}
}
//: Creates New Client
public void newClient(String username,String password) throws
IOException
{
clientName = username;
clientPass = password;
accountNum = (int)(Math.random()*100000);
savingsBal = (int)((Math.random()*100000000)) / 100.0;
currentBal = (int)((Math.random()*100000000)) / 100.0;
BufferedWriter bw = new BufferedWriter (new
FileWriter("ClientDatabase.txt",true));
bw.write(clientName+"_"+clientPass+"_"+accountNum+"_"+currentBal+"_"+savingsBal+"_");
bw.newLine();
bw.close();
}
//: Verifies new Client (THIS IS WHAT DOESN'T WORK, ALONG WITH THE CODE I WILL POST AFTER THIS
public boolean clientVerify(String checkUsername, String checkPassword)
{
try
{
BufferedReader br = new BufferedReader(new FileReader("ClientDatabase.txt"));
String s;
while ((s = br.readLine()) != null){
String line = br.readLine();
String part[] = line.split("_");
if ((part[0].equals(checkUsername))|(part[1].equals(checkPassword))){
accountNum = Integer.parseInt(part[3]);
currentBal = Double.parseDouble(part[4]);
savingsBal = Double.parseDouble(part[5]);
verify = true;
}
}
}
catch(IOException | NumberFormatException e)
{
JOptionPane.showMessageDialog(null, "Error");
}
return verify;
}
}
My Log In Button's code is as follows:
private void btnLoginActionPerformed(java.awt.event.ActionEvent evt) {
String checkUsername = txfUsername.getText();
String checkPassword = txfPassword.getText();
Client cl1 = new Client();
boolean verify = cl1.clientVerify(checkUsername, checkPassword);
if (verify==true){
OptionsPage options = new OptionsPage();
options.setVisible(true);
this.setVisible(false);
}
else{
JOptionPane.showMessageDialog(null, "Username/Password do not match or do not exist.");
}
}
I have been having trouble with my "clientVerify" method, which works for my "Log In Button", as seen above, and I'm not sure which part is wrong.. It doesn't seem to work, and I don't think that my BufferedReader is reading from the text file properly. (That's the only thing I could think of that may be wrong, correct me if it's something else.)
All that comes up no matter the user input is a JOptionPane Message Dialog saying "Error", and then "Username/Password do not match or do not exist". I have checked the text file and the information is all there perfectly seperated by "_".
Another possibility is that my methods aren't changing from what I have entered them as in the default constructor. I'll admit I'm new to methods so that could be a possibility.
Any help will be greatly appreciated.
String line;
Path file = Paths.get("C:\\Users\\nik\\Documents\\Programming\\TextFiles\\Events.txt");
try {
InputStream input = new BufferedInputStream(Files.newInputStream(file));
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
try using this code to try to get to the path of the Text File. Because your methods seems in order, but maybe your program is having trouble finding your text file. Hope this works.
I am trying to read from a file and store the contents into an object called ToDoList(from what I assume is under the GetItem method). Then I am supposed to allow the user to add on to the list. But I am lost on how to create the object and print it.
public class ToDoList {
private ToDoItem[] items;
ToDoItem td = new ToDoItem();
String inputline;
Scanner keyboard = new Scanner(System.in);
int i = 0;
String[] stringArray = new String[100];
private void setItems(ToDoItem[] items) throws FileNotFoundException {
File file = new File("ToDoItems.txt");
Scanner ReadFile = new Scanner(file);
while (ReadFile.hasNext()) {
String ListString = ReadFile.nextLine();
stringArray[100] = (ListString);
}
}
private ToDoItem[] getItems() {
return items;
}
public void addItem(int id, String description) {
stringArray[100] = (td.getId() + td.getDescription());
}
public String[] getAddItem() throws FileNotFoundException {
try (PrintWriter fout = new PrintWriter(new File("ToDoItems.txt"))) {
do {
System.out.println("add to the list? [y/n]");
inputline = keyboard.nextLine();
if ("y".equals(inputline)) {
i++;
stringArray[i] = (td.getId() + ". " + td.getDescription() + "\n");
fout.print(stringArray[i]);
} else {
System.out.println("Here is the list so far:");
}
} while ("y".equals(inputline));
return stringArray;
}
}
#Override
public String toString() {
return "ToDoList{" + "items=" + getItems()
+ '}';
}
I am supposed to use the "getAddItem" method to allow the user to add to the list. But I can't figure out how to add an array to an object. let alone make the object.
A little code to expand on what pininfarina said and to help you get going.
You need a ToDoItem class. Something like this:
public class ToDoItem {
private String id;
private String description;
public ToDoItem(String id, String description) {
this.id = id;
this.description = description;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
Then you need a ToDoList class to hold each item. You backed yours with an Array, but I used an ArrayList:
public class ToDoList {
private ArrayList<ToDoItem> items = new ArrayList<ToDoItem>();
public ToDoList(String fileName) throws FileNotFoundException {
File file = new File(fileName);
Scanner scanner = new Scanner(file);
try {
while (scanner.hasNext()) {
String nextLine = scanner.nextLine();
StringTokenizer tokenizer = new StringTokenizer(nextLine, ",");
String id = tokenizer.nextToken();
String description = tokenizer.nextToken();
items.add(new ToDoItem(id, description));
}
} finally {
scanner.close();
}
}
public void setItems(ArrayList<ToDoItem> newItems) {
this.items.addAll(newItems);
}
public List<ToDoItem> getItems() {
return items;
}
public void addItem(ToDoItem item) {
items.add(item);
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("ToDoList{");
for (ToDoItem item : items) {
builder.append(item.getId() + "," + item.getDescription() + "\n");
}
builder.append("}");
return builder.toString();
}
}
This includes a constructor that reads the file and parses out items. Each line in the file must be something like "1,something" because the tokenizer uses the comma. Note that the Scanner actually destroys the file as it reads it. You might consider using some sort of FileReader instead.
Finally you need a main class to run it. Something like this:
public class RunIt {
private static Scanner keyboard = new Scanner(System.in);
public static void main(String[] args) throws FileNotFoundException {
ToDoList list = new ToDoList("ToDoItems.txt");
try (PrintWriter fout = new PrintWriter(new File("ToDoItems.txt"))) {
String inputLine;
do {
System.out.println("add to the list? [y/n]");
inputLine = keyboard.nextLine();
if ("y".equals(inputLine)) {
System.out.println("enter a to-do using the format 'id,description'");
StringTokenizer tokenizer = new StringTokenizer(keyboard.nextLine(),
",");
String id = tokenizer.nextToken();
String description = tokenizer.nextToken();
list.addItem(new ToDoItem(id, description));
} else {
System.out.println("Here is the list so far:");
System.out.println(list);
}
} while ("y".equals(inputLine));
}
}
}
Please note that there is a lot of room for improvement here (exception handling, more robust file reading, etc), but this should get you started.
You are asking a broad question. Here's some design tips for you.
Create your collection class. This could be named ToDoList. Then create the attributes and behaviors of this class. One attribute will be the collection variable of your to do list items. You can use, List, ArrayList, etc. Behaviors could be add, remove, reorder, and etc.
Create your item class. Again with the attributes and behaviors. Attributes could include what to do, date, importance level, etc.
When you read your file, have your program to instantiate your ToDoItem class for every line, item etc. then save them into the previously created container class which is your ToDoList.
You can use your ToDoList class' addItem method (behavior) to have your users add more items into your ToDoList. If you want to keep the list even after your program closes. You can create a database to store your objects.
Good luck.
I have a server application in Java, that holds a list of Student objects (implementing Serializable). The client application sends a message with an integer - index of Student object to fetch. Then the selected Student is sent to the client, the client modifies its value and sends back. The application however freezes at some point, and it's probably a problem with the lines I emphasized in the code below.
Server:
public class Server {
public static void main(String[] arg) {
ArrayList <Student> studentList = new ArrayList <Student> ();
studentList.add(new Student(170435, "justyna", "kaluzka", new ArrayList <Float>()));
studentList.add(new Student(170438, "michal", "szydlowski", new ArrayList <Float>()));
studentList.add(new Student(170436, "marek", "polewczyk", new ArrayList <Float>()));
studentList.add(new Student(170439, "jakub", "szydlowski", new ArrayList <Float>()));
studentList.add(new Student(170430, "anna", "majchrzak", new ArrayList <Float>()));
studentList.add(new Student(170425, "krzysztof", "krawczyk", new ArrayList <Float>()));
studentList.add(new Student(170445, "adam", "szydlowski", new ArrayList <Float>()));
studentList.add(new Student(170415, "karol", "chodkiewicz", new ArrayList <Float>()));
studentList.add(new Student(170465, "artur", "schopenhauer", new ArrayList <Float>()));
ServerSocket socketConnection = null;
ObjectInputStream serverInputStream = null;
ObjectOutputStream serverOutputStream = null;
try {
socketConnection = new ServerSocket(11111);
System.out.println("Server Waiting");
Socket pipe = socketConnection.accept();
serverOutputStream = new ObjectOutputStream( pipe.getOutputStream());
serverInputStream = new ObjectInputStream( pipe.getInputStream());
int index = serverInputStream.readInt();
System.out.println(index);
// HERE'S WHEN THE PROBLEM STARTS
serverOutputStream.writeObject(studentList.get(index));
Student student = (Student) serverInputStream.readObject();
System.out.println(student.toString());
} catch (IOException e) {
System.out.println(e);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
serverInputStream.close();
serverOutputStream.close();
socketConnection.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Client:
public class Client {
public static void main(String[] arg) {
Student student = null;
Socket socketConnection = null;
ObjectOutputStream clientOutputStream = null;
ObjectInputStream clientInputStream = null;
try {
socketConnection = new Socket("127.0.0.1", 11111);
clientOutputStream = new ObjectOutputStream(socketConnection.getOutputStream());
clientInputStream = new ObjectInputStream(socketConnection.getInputStream());
clientOutputStream.writeInt(0);
student = (Student) clientInputStream.readObject();
student.setFamilyName("Konopnicka");
clientOutputStream.writeObject(student);
} catch (Exception e) {
System.out.println(e);
} finally {
try {
clientOutputStream.close();
clientInputStream.close();
socketConnection.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
My knowledge of client-server sockets is vague, so it's most likely a simple mistake. Any ideas?
EDIT:
Student class
public class Student implements Serializable {
private static final long serialVersionUID = -5169551431906499332L;
private int indexNumber;
private String name;
private String familyName;
private ArrayList<Float> marks;
private float average;
public Student(int indexNumber, String name, String familyName,
ArrayList<Float> marks) {
this.indexNumber = indexNumber;
this.name = name;
this.familyName = familyName;
this.marks = marks;
this.average = 0;
generateMarks();
calculateAverage();
}
public int getIndexNumber() {
return indexNumber;
}
public void setIndexNumber(int indexNumber) {
this.indexNumber = indexNumber;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getFamilyName() {
return familyName;
}
public void setFamilyName(String familyName) {
this.familyName = familyName;
}
public float getAverage() {
return average;
}
public void setAverage(float average) {
this.average = average;
}
/**
* Calculates average of all Student's marks.
*/
public void calculateAverage() {
float sum = 0;
for (int i = 0; i < marks.size(); i++) {
sum += marks.get(i);
}
this.average = sum / marks.size();
}
/**
* Generates a random set of marks for the student.
*/
public void generateMarks() {
for (int i = 0; i < 10; i++) {
addMark(new Random().nextFloat() * 5);
}
}
/**
* Mark getter
*
* #return String representation of marks
*/
public String getMarks() {
String marksstr = "";
for (int i = 0; i < marks.size(); i++) {
marksstr += marks.get(i).toString() + " ";
}
return marksstr;
}
/**
* Adds a mark to the list.
*
* #param mark
*/
public void addMark(float mark) {
marks.add(mark);
}
#Override
public String toString() {
return "Index number:" + indexNumber + "\tName:" + name
+ "\tFamily name:" + familyName + "\t\tAverage:" + getAverage()
+ "\n";
}
}
Initialize your ObjectOutputStream before your ObjectInputSteam on your server.
When you initialize an ObjectInputStream, it waits for "header" data. Your server is waiting for that header data. You need to initialize your ObjectOutputStream first (which sends the header data), THEN your ObjectInputStream.
You can find more about this in here
You must flush your ObjectOutputStream after writing the int. When you write data to a stream, it gets written into a buffer. Data from that buffer is only sent when the stream's buffer is full. An int does not fill it, so you must flush() it to manually send the data from the buffer.