Reading DATE type from text file - java

I have a text file which looks like this
2017-06-14 7932
2017-06-15 10092
2017-06-16 7626
2017-06-17 7613
2017-06-18 11072
2017-06-19 8286
2017-06-20 9293
I am trying to store the values in an ArrayList.
My Code:
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.io.*;
import java.util.Scanner;
public class Sample2 {
public static void main(String[] args) throws FileNotFoundException {
List<Date> l1 = new ArrayList<Date>();
List<Integer> l2 = new ArrayList<Integer>();
Scanner s = new Scanner(new FileReader("t1.txt"));
while (s.hasNext()) {
l1.add(s.nextInt()); !!!!-----Error Line-----!!!!!!!!
l2.add(s.nextInt());
}
s.close();
System.out.println(l1);
System.out.println(l2);;
}
}
I get the Following Error:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The method add(int, Date) in the type List is not
applicable for the arguments (int)
at Sample2.main(Sample2.java:17)
How do I fix it?

Two suggestions:
Create a small class to hold the date and the int that belong together. Why? See Jon Skeet’s Anti-pattern: parallel collections.
Skip the outdated Date class and use the modern LocalDate instead. It models a date without time-of-day, which is exactly what you need here. It also parses your dates right out of the box with no need for an explicit format, so it’s very convenient for your specific purpose.
Below I have just lumped the code together in one class, you will probably want a design with more classes. I will leave that to you.
public class Sample2 {
private LocalDate date;
private int value2;
public Sample2(LocalDate date, int value2) {
this.date = date;
this.value2 = value2;
}
#Override
public String toString() {
return "\nSample2 [date=" + date + ", value2=" + value2 + "]";
}
public static void main(String[] args) throws FileNotFoundException {
List<Sample2> l = new ArrayList<>();
Scanner s = new Scanner(new FileReader("t1.txt"));
while (s.hasNext()) {
l.add(new Sample2(LocalDate.parse(s.next()), s.nextInt()));
}
s.close();
System.out.println(l);
}
}
The program prints
[
Sample2 [date=2017-06-14, value2=7932],
Sample2 [date=2017-06-15, value2=10092],
Sample2 [date=2017-06-16, value2=7626],
Sample2 [date=2017-06-17, value2=7613],
Sample2 [date=2017-06-18, value2=11072],
Sample2 [date=2017-06-19, value2=8286],
Sample2 [date=2017-06-20, value2=9293]]
I will also leave to you to add getters (you may not need setters) and to find better variable names. You know what the numbers mean.

You need to check for an int by using the nextInt() method.
"else" s.next() will return a String.
This will fix your error:
while (s.hasNext()) {
if (s.hasNextInt()) {
int myInt = s.nextInt();
System.out.println(myInt);
} else {
String dateAsString = s.next();
System.out.println(dateAsString);
}
}
When I run this code, I get:
2017-06-14
7932
2017-06-15
10092
2017-06-16
7626
2017-06-17
7613
2017-06-18
11072
2017-06-19
8286
2017-06-20
9293
You will have to convert your date string to a localDate() or Date()

Can you try with below code
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Scanner;
public class Sample2 {
private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
public static void main(String[] args) throws FileNotFoundException {
List<Date> l1 = new ArrayList<Date>();
List<Integer> l2 = new ArrayList<Integer>();
Scanner s = new Scanner(new FileReader("t1.txt"));
while (s.hasNext()) {
l1.add(getDate(s.next()));
l2.add(s.nextInt());
}
s.close();
System.out.println(l1);
System.out.println(l2);
}
private static Date getDate(String next) {
Date date = null;
try {
date = dateFormat.parse(next);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}

Related

non-static variable error when creating own class

I often struggle with non-static variable errors. Not sure I have understood the purpose properly when to use static and not. I have the below code where I'm trying to parse a csv file with three columns (date, time, temperature) in to a class I have defined myself.
This bit gives me a non-static variable error.
TempData objt = new TempData();
If anyone knows what I'm doing wrong I'd be very grateful. I've tried google but can't find anything relevant.
package com.company;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;
import java.text.SimpleDateFormat;
import java.sql.Timestamp;
public class Main {
public static void main(String[] args) {
Date tempDate;
Date tempTime;
Double tempTemperature;
ArrayList<TempData> data = new ArrayList<TempData>();
TempData objt = new TempData();
//Get scanner instance
Scanner scanner = new Scanner(new File("smhi-opendata.csv"));
//Set the delimiter used in file
scanner.useDelimiter(";");
//Get all tokens and store them in some data structure
while (scanner.hasNext())
{
tempDate = new SimpleDateFormat("dd/MM/yyyy").parse(scanner.next());
tempTime = new SimpleDateFormat("hh:mm:ss").parse(scanner.next());
tempTemperature = Double.parseDouble(scanner.next());
objt.Data(tempDate, tempTime, tempTemperature);
data.add(objt);
}
//Do not forget to close the scanner
scanner.close();
}
public class TempData{
private Date date;
private Date time;
private double temperature;
public void Data (Date d, Date t, double te){
date = d;
time = t;
temperature = te;
}
}
}
First off the Data function just updates the values rather than create a new TempData object. Secondly the main function can't use the TempData class where it is currently.
I'd go for something like this instead:
public class TempData {
private Date date;
private Date time;
private double temperature;
public TempData(Date date, Date time, double temperature) {
this.date = date;
this.time = time;
this.temperature = temperature;
}
public static void main(String[] args) throws Exception {
Date tempDate;
Date tempTime;
Double tempTemperature;
ArrayList<TempData> data = new ArrayList<TempData>();
// Get scanner instance
Scanner scanner = new Scanner(new File("smhi-opendata.csv"));
// Set the delimiter used in file
scanner.useDelimiter(";");
// Get all tokens and store them in some data structure
while (scanner.hasNext()) {
tempDate = new SimpleDateFormat("dd/MM/yyyy").parse(scanner.next());
tempTime = new SimpleDateFormat("hh:mm:ss").parse(scanner.next());
tempTemperature = Double.parseDouble(scanner.next());
TempData objt = new TempData(tempDate, tempTime, tempTemperature);
data.add(objt);
}
// Do not forget to close the scanner
scanner.close();
}
}
The problem is that you are accessing a non static class from a static context. The main method (public static void main() {}) has the keyword static so it is in the class (static) context. Your inner class TempData is not static, so it belongs to the instance (non static) context.
You can access the class context from instance context, but not vice versa. So you have tow options:
Move your TempData class to the static context:
public class Main {
public static void main(String[] args) {
// ...
TempData objt = new TempData();
// ...
}
public static class TempData{
// ...
}
}
Or access your TempData from non static context. For example:
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
// ...
TempData objt = new TempData();
// ...
}
public class TempData {
// ...
}
}
To read more about this you can follow this official explanation.

ToDoItem, MyList & Driver classes

Here are my instructions:
This assignment is already past due and my professor said he would comment on it to help me understand but I think he is too busy & it's irking my soul that I can't get it right so.... here i am... Any help would be wonderful.
ToDo List
You will be handing in 2 classes. ToDoItem.java (defines the data type of a To Do Item) and MyList.java (the driver that allows the user to enter data, create ToDoItems, and manage ToDoItems).
Design a class for a ToDoItem. A ToDoItem keeps track of an item you need to do (as a string), the date it is due (hmmm, what is a good way to do this?), the priority of that item (1 is high, 2 is medium, 3 is low), and if that item is or is not completed.
Sketch-out a rough UML diagram of what this class would look like and what methods you would need for this class. You must include this with your assignment. You may use a CASE tool like ArgoUML or you can simply hand draw the diagram and submit a picture with your assignment.
You must provide a constructor that accepts arguments for this class to set the object's default state.
Write an overloaded method so that a user can set priority by int (1, 2, 3) or String ("high", "medium", "low").
Then, write a simple menu-driven program that allows a user to create ToDo Items, delete them, view them all unsorted, and mark them as completed. Please see the attached file MyList.java for a small framework to help make your menu system more organized.
ToDo Notes & Hints
The attached file MyList.java is a basic framework for a simple command-line driven ToDo list. Use this as the basis for your ToDo assignment. There is a lot missing from this starter file but it will help you get up and running quicker.
import java.util.ArrayList;
import java.util.Scanner;
public class MyList {
public static ArrayList todoItems = new ArrayList();
public static void main(String[] args) {
while(true) {
printMenu();
processInput();
}
}
public static void printMenu() {
System.out.println("[a]dd an item");
System.out.println("[p]rint all");
System.out.println("[q]uit");
}
public static void processInput() {
Scanner s = new Scanner(System.in);
String input = s.next();
if(input.equals("a")) {
//addToDoItem();
}
else if(input.equals("p")) {
//printAll();
}
else if(input.equals("q")) {
System.exit(0);
}
}
// implement rest of processInput methods here
}
Each feature such as create, view, delete, and mark read should be defined as a method so that your code can be easily read.
Your ToDoItem class should have NO code related to user interface in it. Keep your user interface code separate from your data (this advice is based on a pattern called Model-View-Controller or MVC). This means your ToDoItem class might be pretty basic and that your "driver" file with your main method is doing most of the work.
Use an Array or ArrayList to store your ToDoItems. Reference individual ToDoItems by their index in that data structure (print the index of each item when printing all ToDoItems).
Once a ToDoItem is created it can NOT be edited beyond being marked as completed. If the user mistypes a date or incorrectly spells the title that item can only be deleted and then recreated to be fixed. This is to simplify the assignment.
Again, marking an item as complete/incomplete is the only aspect of a ToDoItem that can be edited. Objects that cannot be edited are called immutable.
ToDo Program Thoughts
Here are some things to think about that we will address in a few weeks in this course. I included these items now so you can start to think about them.
What if we wanted to sort our items by date due or by priority or by both? - -Don't write this, just think about how we might do this.
What makes one ToDo -item less than, equal to, or greater than another?
We are writing a lot of code to manage our array of ToDoItems. What, if anyways, might we simplify this?
I have a video of a demo of the program: https://youtu.be/9eWkn7uOLs0
Here are the codes I have written so far. I am stuck and having trouble parsing my date and getting it to print out.
MyList.java
import java.util.Scanner;
import java.util.ArrayList;
import java.io.*;
import java.text.*;
public class MyList {
public static ArrayList<ToDoItem> toDoItems = new ArrayList<>();
public static Scanner k = new Scanner(System.in);
private static String description;
private static String dueDate;
public static void main(String[] args) throws ParseException {
while(true) {
printMenu();
processInput();
}
}
public static void printMenu() {
System.out.println("[a]dd an item");
System.out.println("[d]elete an item");
System.out.println("[t]oggle complete");
System.out.println("[p]rint all");
System.out.println("[q]uit");
}
public static void processInput() throws ParseException{
Scanner s = new Scanner(System.in);
String input = s.next();
if(input.equals("a")) {
addToDoItem();
}
else if(input.equals("d")) {
//deleteToDoItem();
}
else if(input.equals("t")) {
// toggleComplete();
}
else if(input.equals("p")) {
printAll();
}
else if(input.equals("q")) {
System.exit(0);
}
}
public static ToDoItem addToDoItem() throws ParseException {
ToDoItem newItem;
newItem = null;
System.out.print("Enter an item to add to list: ");
String desc = k.nextLine();
if(desc.trim().length()==0) return newItem;
System.out.print("Enter Date (MM/dd/YYYY): ");
String dueDate = k.nextLine();
System.out.print("Enter priority between 1 and 3 (3 being the highest): ");
String prior = k.nextLine();
int p = Integer.parseInt(prior);
if(dueDate.trim().length()==0){
newItem = new ToDoItem(desc);
}
else {
newItem = new ToDoItem(desc, dueDate);
}
newItem.setPriority(p);
return newItem;
//toDoItems.add(new ToDoItem(desc, p, dueDate));
}
public static void printAll() throws ParseException {
ToDoItem item = new ToDoItem();
System.out.println(item);
//ToDoItem task = newItem.get(i);
// ***************
// You should not need to create ToDoItems here
// This method should loop through your array and print out each item
// Since you have a toString() method you can print the objects by passing
// them into like so inside of a loop System.out.println( item.get(i) )
//for(int i = 0; i < newItem.size(); i++) {
// System.out.println(toDoItems.get(i));
// }
// for(ToDoItem myItem : toDoItems) {
//ToDoItem myItem = toDoItems.get(i);
//System.out.println(myItem);
// System.out.println(myItem.getDescription()+" -"+myItem.getPriority()+"- ("+myItem.getDueDate()+")");
}
}
//public static void deleteToDoItem() {
// **********
// You won't need a loop here, you can directly
// delete the item at the given index.
// Prompt for an int, read in the int, then call item.remove(i);
//System.out.print("Enter index of item to delete: ");
//int delete = k.nextInt();
//toDoItems.remove(i);
// }
// public static void toggleComplete() {
/////
// }
//}
ToDoItem.java
import java.text.*;
import java.util.Date;
//import java.lang.NullPointerException;
public class ToDoItem {
private String description;
private Date dueDate;
private int priority;
DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
public ToDoItem() {
}
public ToDoItem(String desc) {
description = desc;
dueDate = null;
priority = 0;
}
public ToDoItem(String desccription, String dDate) throws ParseException {
this.description = description;
dueDate = df.parse(dDate.trim());
}
public String toString() {
if(dueDate != null) {
return( description + " -"+priority+"- " + "Date not Set");
}
else {
return( description + " -"+priority+"- " + df.format(dueDate));
}
}
public void setPriority( int prio) {
if(prio<0) this.priority = 0;
else if(prio > 3) this.priority = 3;
else this.priority = prio;
}
public int getPriority() {
return this.priority;
}
public void setDueDate(String date) throws ParseException {
Date d = df.parse(date.trim());
this.dueDate = d;
}
public String getDescription() {
return description;
}
public String getDueDate() {
if(dueDate == null) return "";
return df.format(dueDate);
}
}
If you have a problem with parsing and printing out your Date-type maybe this could help you:
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
String dateString = sdf.format(new Date());
Date date = null;
try {
date = sdf.parse("10/16/2015");
} catch (ParseException objcPException) {
// TODO Auto-generated catch block
objcPException.printStackTrace();
}
System.out.println(date);
System.out.println(dateString);
You have to change this method:
public ToDoItem(String desccription, String dDate) throws ParseException {
this.description = description;
dueDate = df.parse(dDate.trim());
}
to this:
public ToDoItem(String desccription, String dDate) throws ParseException {
this.description = description;
dueDate = sdf.parse(dDate);
}
and switch your DateFormat to SimpleDateFormat like this in my example.
Maybe you have to validate the form of the input first (MM/dd/yyyy) before parsing.
Replace the following code
DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
with statement below and try
SimpleDateFormat df = new SimpleDateFormat("MM/dd/YYYY");
So, the constructor will use this dateformat to parse the input.
dueDate = df.parse(dDate.trim());
When user presents date in a format (MM/dd/YYYY) and is read as a string, best way is to parse it using dateformat. Check the following similar example from (stackoverflow). You can run it and check.
String string = "January 2, 2010";
DateFormat format = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH);
Date date = format.parse(string);
System.out.println(date);
Hope it helps.

When using the Java Formatter class, why will the constructor create a txt file, but not write to it?

This code works, which is odd:
import java.util.*;
import java.io.*;
public class FileWork {
private Formatter r;
public void openFile(){
try{
r = new Formatter("c:\\employees.txt");
}
catch(Exception e){
System.out.println("You got an error");
}
}
public void addRecords(){
r.format("%d%s%s%n", 34 , " Matt ", "Jenkins");
r.format("%d%s%s%n", 36 , " John ", "Jackson");
}
}
Then in another class I call the methods.
public class FileWork2 {
public static void main(String[] args) {
FileWork g = new FileWork();
g.openFile(); //creates file
g.addRecords(); //adds records
}
}
But the following code does not work:
import java.io.FileNotFoundException;
import java.util.Formatter;
public class FileWork3 {
public static void main(String[] args) throws FileNotFoundException {
final Formatter x = new Formatter("c:\\GuestList2.txt");
x.format("%d", 10);
}
}
This 2nd set of code creates the file GuestList2.txt, but writes nothing to it. It is blank. It seems this only works when the Formatter is set as public and private, and called from another class. I am so confused on the proper way to use the format method.
It was just because I needed to run the close() method. Now it works fine, and I have tried it in different ways, with Final, with static methods, and it's writing output fine now. Thanks for the links and comments.

sort descendingly based on multiple parameters in Java

I have input of multiple strings where I parse each one to fetch certain data and then display them accordingly. The point is I need to sort them accodring to some parameters before displaying them.
To clarify:
String s1 = "a1 5 2014-12-05";
String s2 = "a2 10 2014-12-06";
String s3 = "a3 5 2014-12-04":
After pasring each string, I need to sort them descendingly first according to the second parameter and then according to the date whenever I reach a tie for example.
Output should be:
a2, a1, a3
Any idea how can this be achieved or if I could change the way to a more efficient one?!
You can parse the data and use Collections#sort. Your class can define some natural ordering using Comparable and in case if you want to sort descending then just pass Comparator.reverseOrder() as second arg to Collections#sort like this
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
public class DateSorter {
static class Entry implements Comparable<Entry> {
String id;
int num;
Date date;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
public Entry(String id, int num, String date) throws ParseException {
this.id = id;
this.num = num;
this.date = sdf.parse(date);
}
#Override
public int compareTo(Entry o) {
return date.compareTo(o.date);
}
#Override
public String toString() {
return id + '\'';
}
}
public static void main(String[] args) throws ParseException {
String s1 = "a1 5 2014-12-05";
String s2 = "a2 10 2014-12-06";
String s3 = "a3 5 2014-12-04";
String[] split = s1.split(" ");
List<Entry> entries = new ArrayList<>();
entries.add(new Entry(split[0], Integer.parseInt(split[1]), split[2]));
split = s2.split(" ");
entries.add(new Entry(split[0], Integer.parseInt(split[1]), split[2]));
split = s3.split(" ");
entries.add(new Entry(split[0], Integer.parseInt(split[1]), split[2]));
Collections.sort(entries, new Comparator<Entry>() {
#Override
public int compare(Entry o1, Entry o2) {
return o2.compareTo(o1);
}
});
System.out.println(entries);
}
}
Output
[a2', a1', a3']

Java exception error when using Scanner

Can someone please help me see what the problem is. I realise that using
String kind = sc.next();
might bring a problem. if that's the issue how do i fix it. Thank you in advance. Here is the code.
import java.io.*;
import java.util.*;
public abstract class Account {
protected static AccountNumber accountNumber;
protected Customer customer = null; // not to be used yet
public abstract MeterNumber[] getMeterNumbers();
public abstract boolean exists(String meterNumber, String tariff);
public static Account load(Scanner sc) {
while (sc.hasNextLine()) {
AccountNumber accountNumber = AccountNumber.fromString(sc.nextLine());
String kind = sc.next();
sc.nextLine();
if (kind.equals("D")) {
return new DomesticAccount(sc, accountNumber);
} else {
return new CommercialAccount(sc, accountNumber);
}
} {
return null;
}
}
}
The code in main is as follows.
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
public class Testt {
public static void main(String[] args) {
Account.load(new Scanner("Accounts3.txt"));
Map <AccountNumber, String> map1 = new HashMap <AccountNumber, String>();
map1.put(Account.accountNumber, "hello");
System.out.println(map1);
}
}
and this is the error I am getting.
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1371)
at Account.load(Account.java:20)
at Testt.main(Testt.java:14)
Your are creating scanner on string object. Which is just "Accounts3.txt". Which is just one line.
http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#Scanner(java.lang.String)
I think you need to create scanner on file.
Refere this:
http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#Scanner(java.io.File)
So your main method will create scanner like this:
Account.load(new Scanner(new java.io.File("Accounts3.txt")));

Categories

Resources