ArrayList<String> not being adding to object (JAVA) - java

Programme class which contains a code and module(s)
import java.util.ArrayList;
public class Programme {
private ArrayList<String> modules = new ArrayList<String>();
private String ProgrammeCode;
public Programme(String ProgrammeName) {
this.ProgrammeCode = ProgrammeName;
if (modules.size() > 0) {
modules.clear(); //clear if something in modules
}
}
public Programme(String programmeCode, ArrayList<String> moduleList) {
this.ProgrammeCode = programmeCode;
modules = moduleList;
}
public void addModule(String name) {
if (name != null && !name.equals("")) {
modules.add(name);
}
}
public String getProgrammeCode() {
return ProgrammeCode;
}
public ArrayList<String> getModules() {
return modules;
}
public int getModuleCount() {
return modules.size();
}
}
This is in the class that reads csv files and stores them into type Programme, but i have a problem adding the strings into modules.
public ArrayList<Programme> loadProgrammes() {
ArrayList<String> modules = new ArrayList<String>(); //.... modules are being read from
//a csv file and have done multiple tests and its working correctly
modules.add(".....");
//PROBLEM HERE
programmes.add(new Programme(programmeStrings.get(i).get(0), modules));
//this displays as i want it to e.g. when added:3:[MA4102, CS4092, CS4162]
System.out.print("when added:" + programmes.get(i).getModuleCount() + ":" + modules);
//where as this doesn't work e.g. //Finished list:3 //LM023 0 []
//LM051 0 [] //LM110 0 []
System.out.println("\nFinished list:" + programmes.size());
for (int t = 0; t < programmes.size(); t++) {
System.out.println(programmes.get(t).getProgrammeCode() + " " + programmes.get(t).getModuleCount() + " "
+ programmes.get(t).getModules());
}
return programmes;
}
I'm not sure what is going wrong. Why isn't it adding the modules to the programme object

Related

Why is my Stack empty? EmptyStackException

I'm working with Stacks in Java at the moment.
The problem I'm facing is that I want to create a Stack which stores items of the type "candy".
I want to add that "candy" at the Producer.java
But when I run the code shown below I get the error:
Exception in thread "main" java.util.EmptyStackException
at java.util.Stack.peek(Stack.java:102)
at java.util.Stack.pop(Stack.java:84)
at app.fachinformatiker.myMashup.Model.Consumer.(Consumer.java:10)
at app.fachinformatiker.myMashup.Main.Main.initializeConsumers(Main.java:84)
at app.fachinformatiker.myMashup.Main.Main.main(Main.java:42)
These are the corresponding lines
Consumer.java:10
String Candy = candyStack.pop();
Main.java:84
consumerList.add(new Consumer(candyStack));
Main.java:42
initializeConsumers();
I don't get it why my stack isn't properly filled.
Below you will find some snippets of my code.
If you want to download my whole code and run it in an IDE of your choice (I use IntelliJ IDEA), here's a direct link to the archive on GitHub (specific commit) : https://github.com/fachinformatiker/myMashup/archive/97e3ffb.zip
Here's some snippets of my code:
In my Main.java
private static final Stack<String> candyStack = new Stack<>();
private static final ArrayList<Producer> producerList = new ArrayList<>();
private static final ArrayList<Consumer> consumerList = new ArrayList<>();
...
private static void startProducers() {
for (int i = 0; i < producerList.size(); i++) {
System.out.println("I would start producer Nr. " + i + " now.");
producerList.get(i).start();
}
}
private static void startConsumer() {
for (int i = 0; i < consumerList.size(); i++) {
Debug.gebeInfoAus("I would start consumer Nr. " + i + " now.");
consumerList.get(i).start();
}
}
private static void initializeProducers() {
if (ArgController.istAusgewertet) {
Debug.gebeInfoAus("Producer istAusgewertet");
return;
}
for (int i = 0; i < ArgController.getAnzahlProduzenten(); i++) {
Debug.gebeInfoAus("Producer Nr. " + i + " added to candyStack");
producerList.add(new Producer(candyStack, i));
}
}
in my Producer.java
public class Producer {
private Candy candy = new Candy();
private String myCandy;
int hell = candy.getHell();
String hope = candy.getHope();
public Producer(Stack<String> candyStack, int i) {
myCandy = i + ";" + hell + ";" + hope;
candyStack.push(myCandy);
Debug.gebeInfoAus(myCandy);
}
public void start() {
}
}
In my Consumer.java
public class Consumer {
public Consumer(Stack<String> candyStack) {
String Candy = candyStack.pop();
Debug.gebeInfoAus(Candy);
}
public void start() {
}
}

Using array as key for hashmap java

i have a method that puts some value(obtained from an excel file) into a hashmap with an array as the key
public HashMap<List<String>, List<String[]>> sbsBusServiceDataGnr() throws
IOException
{
System.out.println(engine.txtY + "Processing HashMap "
+ "sbsBusServiceData..." + engine.txtN);
int counterPass = 0, counterFail = 0, stopCounter = 0;
String dataExtract, x = "";
String[] stopInfo = new String[3];
List<String[]> stopsData = new ArrayList<String[]>();
List<String> serviceNum = new Vector<String>();
HashMap<List<String>, List<String[]>> sbsBusServiceData =
new HashMap<List<String>, List<String[]>>();
String dataPath = this.dynamicPathFinder(
"Data\\SBS_Bus_Routes.csv");
BufferedReader sbsBusServiceDataPop = new BufferedReader(
new FileReader(dataPath));
sbsBusServiceDataPop.readLine();
//Skips first line
while ((dataExtract = sbsBusServiceDataPop.readLine()) != null) {
try {
String[] dataParts = dataExtract.split(",", 5);
if (!dataParts[4].equals("-")){
if (Double.parseDouble(dataParts[4]) == 0.0){
sbsBusServiceData.put(serviceNum, stopsData);
String serviceNum1 = "null", serviceNum2 = "null";
if(!serviceNum.isEmpty()){
serviceNum1 = serviceNum.get(0);
serviceNum2 = serviceNum.get(1);
}
System.out.println("Service Number " + serviceNum1
+ ":" + serviceNum2 + " with " + stopCounter
+ " stops added.");
stopCounter = 0;
//Finalizing previous service
serviceNum.Clear();
serviceNum.add(0, dataParts[0]);
serviceNum.add(1, dataParts[1]);
//Adding new service
}
}
stopInfo[0] = dataParts[2];
stopInfo[1] = dataParts[3];
stopInfo[2] = dataParts[4];
stopsData.add(stopInfo);
//Adding stop to service
stopCounter++;
counterPass++;
}
catch (Exception e) {
System.out.println(engine.txtR + "Unable to process "
+ dataExtract + " into HashMap sbsBusServiceData."
+ engine.txtN + e);
counterFail++;
}
}
sbsBusServiceDataPop.close();
System.out.println(engine.txtG + counterPass + " number of lines"
+ " processed into HashMap sbsBusServiceData.\n" + engine.txtR
+ counterFail + " number of lines failed to process into "
+ "HashMap sbsBusServiceData.");
return sbsBusServiceData;
}
//Generates sbsBusServiceDataGnr HashMap : 15376 Data Rows
//HashMap Contents: {ServiceNumber, Direction},
// <{RouteSequence, bsCode, Distance}>
this method work for putting the values into the hashmap but i cannot seem to get any value from the hashmap when i try to call it there is always a nullpointerexception
List<String> sbsTest = new Vector<String>();
sbsTest.add(0, "10");
sbsTest.add(1, "1");
System.out.println(sbsBusServiceData.get(sbsTest));
try{
List<String[]> sbsServiceResults = sbsBusServiceData.get(sbsTest);
System.out.println(sbsServiceResults.size());
String x = sbsServiceResults.get(1)[0];
System.out.println(x);
} catch(Exception e){
System.out.println(txtR + "No data returned" + txtN + e);
}
this is a sample of the file im reading the data from:
SBS
How can i get the hashmap to return me the value i want?
Arrays are not suitable as keys in HashMaps, since arrays don't override Object's equals and hashCode methods (which means two different array instances containing the exact same elements will be considered as different keys by HashMap).
The alternatives are to use a List<String> instead of String[] as the key of the HashMap, or to use a TreeMap<String[]> with a custom Comparator<String[]> passed to the constructor.
If you are having fixed array size then the example I'm posting might be useful.
Here I've created two Object one is Food and Next is Product.
Here Food object is use and added method to get string array.
public class Product {
private String productName;
private String productCode;
public Product(String productName, String productCode) {
this.productName = productName;
this.productCode = productCode;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getProductCode() {
return productCode;
}
public void setProductCode(String productCode) {
this.productCode = productCode;
}
}
Food Model Class: Use as a Object instead of String[] and achieve String[] functionality.
public class Food implements Comparable<Food> {
private String type;
private String consumeApproach;
public Food(String type, String consumeApproach) {
this.type = type;
this.consumeApproach = consumeApproach;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getConsumeApproach() {
return consumeApproach;
}
public void setConsumeApproach(String consumeApproach) {
this.consumeApproach = consumeApproach;
}
public String[] FoodArray() {
return new String[] { this.type, this.consumeApproach };
}
//Implement compareTo method as you want.
#Override
public int compareTo(Food o) {
return o.getType().compareTo(this.type);
}
}
Using HashMap example
public class HashMapKeyAsArray {
public static void main(String[] args) {
HashMap<Food,List<Product>> map = dataSetLake();
map.entrySet().stream().forEach(m -> {
String[] food = m.getKey().FoodArray();
Arrays.asList(food).stream().forEach(f->{
System.out.print(f + " ");
});
System.out.println();
List<Product> list = m.getValue();
list.stream().forEach(e -> {
System.out.println("Name:" + e.getProductName() + " Produc Code:" + e.getProductCode());
});
System.out.println();
});
}
private static HashMap<Food,List<Product>> dataSetLake(){
HashMap<Food,List<Product>> data = new HashMap<>();
List<Product> fruitA = new ArrayList<>();
fruitA.add(new Product("Apple","123"));
fruitA.add(new Product("Banana","456"));
List<Product> vegetableA = new ArrayList<>();
vegetableA.add(new Product("Potato","999"));
vegetableA.add(new Product("Tomato","987"));
List<Product> fruitB = new ArrayList<>();
fruitB.add(new Product("Apple","123"));
fruitB.add(new Product("Banana","456"));
List<Product> vegetableB = new ArrayList<>();
vegetableB.add(new Product("Potato","999"));
vegetableB.add(new Product("Tomato","987"));
Food foodA = new Food("Fruits","Read To Eat");
Food foodB = new Food("Vegetables","Need To Cook");
Food foodC = new Food("VegetablesC","Need To Cook C");
data.put(foodA, fruitB);
data.put(foodB, vegetableB);
data.put(foodA, fruitA);
data.put(foodC, vegetableA);
return data;
}
Using TreeMap example
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.TreeMap;
public class TreeMapKeyAsArray {
public static void main(String[] args) {
TreeMap<Food, List<Product>> map = dataSetLake();
map.entrySet().stream().forEach(m -> {
String[] food = m.getKey().FoodArray();
Arrays.asList(food).stream().forEach(f->{
System.out.print(f + " ");
});
System.out.println();
List<Product> list = m.getValue();
list.stream().forEach(e -> {
System.out.println("Name:" + e.getProductName() + " Produc Code:" + e.getProductCode());
});
System.out.println();
});
}
private static TreeMap<Food, List<Product>> dataSetLake() {
TreeMap<Food, List<Product>> data = new TreeMap<>();
List<Product> fruitA = new ArrayList<>();
fruitA.add(new Product("Apple", "123"));
fruitA.add(new Product("Banana", "456"));
List<Product> vegetableA = new ArrayList<>();
vegetableA.add(new Product("Potato", "999"));
vegetableA.add(new Product("Tomato", "987"));
List<Product> fruitB = new ArrayList<>();
fruitB.add(new Product("Apple", "123"));
fruitB.add(new Product("Banana", "456"));
List<Product> vegetableB = new ArrayList<>();
vegetableB.add(new Product("Potato", "999"));
vegetableB.add(new Product("Tomato", "987"));
Food foodA = new Food("Fruits", "Read To Eat");
Food foodB = new Food("Vegetables", "Need To Cook");
data.put(foodA, fruitB);
data.put(foodB, vegetableB);
data.put(foodA, fruitA);
data.put(foodB, vegetableA);
return data;
}
}

Creating an Hierarchy-Object with an undefined number of childs

I am currently working on a "code parser" parsing Valve Map Format (.vmf files) into a java readable Object.
In vmf files,
there are 2 types of objects: Classes and Properties.
classes have a name and can contain other classes and properties.
properties have a name and an unlimited number of values.
Therefore I created a VMFClass Object Class and a VMFProperty Object Class.
I created a List with self-created HierarchyObjects, containing the VMFClass/VMFProperty Object, an UUID and the parentUUID.
The VMFClass Object Contains 2 Lists one with sub-VMFClasses, one with properties.
My Problem is that I have no clue on how to achieve that a Class contains all of its subclasses, since I can't tell how much subclasses the subclasses have and so on...
Here is my Code (Github):
HierachyObject:
package net.minecraft.sourcecraftreloaded.utils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class HierarchyObject {
private static Map<Long, Long> usedUUIDs = new HashMap<>();
private long parentUUID;
private long UUID;
private Object object;
/**
*
* #param Object
* #param parent -1 is maximum level
*/
public HierarchyObject(Object object, long parent) {
this.object = object;
this.parentUUID = parent;
while (true) {
long random = (long) (Math.random() * Long.MAX_VALUE);
if (usedUUIDs.containsKey(random)) {
this.UUID = random;
usedUUIDs.put(random, parent);
break;
}
}
}
public long getUUID() {
return UUID;
}
public long getParentUUID() {
return parentUUID;
}
public static long getParentUUIDbyUUID(long UUID) {
if (usedUUIDs.containsKey(UUID)) {
return usedUUIDs.get(UUID);
}
return -1;
}
public Object getObject() {
return object;
}
public static boolean hasChild(long UUID){
if(usedUUIDs.containsValue(UUID)){
return true;
}
if(UUID == -1){
return true;
}
return false;
}
public boolean hasChild(){
return hasChild(this.UUID);
}
public static long[] getChildUUIDs(long UUID){
if(hasChild(UUID)){
List<Long> cUUIDs = new ArrayList<>();
for(int i = 0; i < usedUUIDs.size(); i++){
for (Map.Entry<Long, Long> e : usedUUIDs.entrySet()) {
if(e.getValue().longValue() == UUID){
cUUIDs.add(e.getKey());
}
}
}
return ListUtils.toPrimitivebyList(cUUIDs);
}
return null;
}
}
VMFProperty:
package net.minecraft.sourcecraftreloaded.source;
public class VMFProperty{
private String name;
private String[] values;
public VMFProperty(String name, String... values) {
this.name = name;
this.values = values;
}
public String getName() {
return name;
}
public String[] getValues() {
return values;
}
#Override
public boolean equals(Object paramObject){
if(paramObject instanceof VMFProperty){
return ((VMFProperty)paramObject).name.equals(this.name) && ((VMFProperty)paramObject).values.equals(this.values);
}
return false;
}
}
VMFClass:
package net.minecraft.sourcecraftreloaded.source;
import java.util.List;
public class VMFClass{
private List<VMFClass> classes;
private List<VMFProperty> properties;
private String name;
public VMFClass(String name, List<VMFClass> classes, List<VMFProperty> properties) {
this.name = name;
this.classes = classes;
this.properties = properties;
}
public String getName() {
return name;
}
public List<VMFClass> getClasses() {
return classes;
}
public List<VMFProperty> getProperties() {
return properties;
}
public void add(VMFClass vmfclass) {
classes.add(vmfclass);
}
public void add(VMFProperty vmfproperty) {
properties.add(vmfproperty);
}
public void remove(VMFClass vmfclass) {
classes.remove(vmfclass);
}
public void remove(VMFProperty vmfproperty) {
properties.remove(vmfproperty);
}
#Override
public boolean equals(Object paramObject){
if(paramObject instanceof VMFClass){
return ((VMFClass)paramObject).properties.equals(this.properties) && ((VMFClass)paramObject).classes.equals(this.classes) && ((VMFClass)paramObject).name.equals(this.name);
}
return false;
}
}
VMFObject (the class executing all the code):
package net.minecraft.sourcecraftreloaded.source;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.sourcecraftreloaded.utils.HierarchyObject;
public class VMFObject {
private String rawfile = "";
private List<VMFClass> toplevelclasses;
private static final String INVALID_CHARS = "\\*,;<>|?=`´#'+~^°!§$%&()[].:-_";
public VMFObject(List<VMFClass> toplevelclasses) {
this.toplevelclasses = toplevelclasses;
}
public VMFObject() {
this(new ArrayList<VMFClass>());
}
public void write(File file) {
VMFWriter.write(file, rawfile);
}
public VMFObject read(File file) throws VMFParsingException {
this.rawfile = VMFReader.read(file);
parse();
return this;
}
public List<VMFClass> getClasses() {
return toplevelclasses;
}
private void parse() throws VMFParsingException {
evaluate();
get();
}
private void evaluate() throws VMFParsingException {
char[] textchars = rawfile.toCharArray();
int[] c = new int[]{0, 0, 0};
int line = 0;
int linepos = 0;
for (int i : textchars) {
linepos++;
if (textchars[i] == '\n') {
line++;
linepos = 0;
c[3] = 0;
if (c[3] % 2 != 0) {
throw new VMFParsingException("Invalid quotes on line" + line + ":" + linepos);
}
}
if (textchars[i] == '{') {
c[1]++;
}
if (textchars[i] == '}') {
c[2]++;
}
if (textchars[i] == '"') {
c[3]++;
if (c[1] - c[2] == 0) {
}
}
if (textchars[i] == '/' && textchars[i + 1] == '/') {
while (true) {
i++;
if (textchars[i] == '\n') {
break;
}
}
}
if (textchars[i] == '/' && textchars[i + 1] == ' ') {
throw new VMFParsingException("Invalid Character '/' on line" + line + ":" + linepos);
}
if (INVALID_CHARS.indexOf(textchars[i]) != -1) {
throw new VMFParsingException("Invalid Character '" + textchars[i] + "' on line" + line + ":" + linepos);
}
}
if (c[1] != c[2]) {
throw new VMFParsingException("Unbalanced brackets in vmf File");
}
}
public void add(VMFClass vmfclass) {
toplevelclasses.add(vmfclass);
}
private void get() throws VMFParsingException {
List<HierarchyObject> content = new ArrayList<>();
long curparent = -1;
String[] text = rawfile.split("\n");
for (int i = 0; i < text.length; i++) {
String line = text[i].trim();
if (line.startsWith("//")) {
continue;
} else {
byte quotec = 0;
char[] linechar = line.toCharArray();
boolean readp = false;
List<String> reads = new ArrayList<>();
byte creads = 0;
for (int y = 0; y < linechar.length; y++) {
if (linechar[y] == '/' && linechar[y + 1] == '/') {
break;
}
if (linechar[y] == '"') {
quotec++;
if (quotec % 2 == 0) {
readp = false;
creads++;
} else {
readp = true;
}
}
if (readp) {
reads.set(creads, reads.get(creads) + linechar[y]);
}
if (linechar[y] == '{') {
HierarchyObject object = new HierarchyObject(new VMFClass(line.substring(line.substring(0, y).lastIndexOf(' '), y).trim(), null, null), curparent);
content.add(object);
curparent = object.getUUID();
}
if (linechar[y] == '}') {
curparent = HierarchyObject.getParentUUIDbyUUID(curparent);
}
}
content.add(new HierarchyObject(new VMFProperty(reads.remove(0), reads.toArray(new String[reads.size()])), curparent));
}
}
buildObject(content);
}
private void buildObject(List<HierarchyObject> content) {
long curUUID = -1;
for(int i = 0; i < HierarchyObject.getChildUUIDs(curUUID).length; i++){
HierarchyObject.getChildUUIDs(curUUID);
}
//TODO implement
}
}
the //TODO part is where the Hierachy Object should get "converted" to the actual object.
Overview
It seems to me that your class layout is overcomplicated.
Let's try to simplify it...
What you have described with the VMF model is essentially a linked-list Tree.
Here's what the model looks like:
[.vmf file] (root)
/ \
_____/ \ _____
/ \
/ \
(VMFClass) (VMFClass)
/ \ / \
/ \ / \
/ \ / \
(VMFClass) (VMFProperties) (VMFClass) (VMFProperties)
/ \
/ \
/ \
(VMFClass) (VMFProperties)
What you need:
A Parser class (in your case, you have VMFObject, but lets call this class VMFParser).
The VMFClass and VMFProperty classes which you have are fine.
What you don't need:
The HierarchyObject class. The VMFParser can be the main controller and container for the hierarchy (e.g. the linked-list Tree model).
All the UUIDs (parent, child, etc.) These are just complicated things, but I see why you have them. You don't need them to track the hierarchy - Java will do this for us!!
VMFClass
public class VMFClass
{
// name of the class
private String name;
// reference back up to the parent
private VMFClass parentClass = null;
// all direct children go here
private List<VMFClass> children = new ArrayList<VMFClass>();
// I don't think you need a list of properties here since your VMFProperty class holds onto an array of properties
private VMFProperty properties;
// set the parent of this class
public void setParent (VMFClass parent)
{
this.parentClass = parent;
}
// get the direct children
public List<VMFClass> getChildren()
{
return this.children;
}
// rest of methods...
}
VMFParser
class VMFParser
{
private String rawfile = "";
// this is really the container for everything - think of it as the file shell
private VMFClass root = new VMFClass("root", null, null);
// construct yourself with the file
public VMFParser (String fileName)
{
this.rawfile = fileName;
}
public void parse ()
{
// all the parsing code goes here
read();
evaluate();
get();
// now at this point your hierarchy is built and stored in the
// root object in this class.
// Use the traverse method to go through it
}
private void get() throws VMFParsingException
{
// keep a reference to the current VMFClass parent
// starts out as root
VMFClass currParentClass = root;
// main parse loop
for (...)
{
// if you find a class
VMFClass currClass = new VMFClass(/* params here */);
// add this class to the parent
currParentClass.add(currClass);
// set the parent of this class
currClass.setParent(currParentClass);
// if you find a property
// parse and add all the properties to the property
VMFProperty property = new VMFProperty (/* value params here */);
// attach this property to the last VMF class that got parsed
currClass.setPoperties(property);
// If you nest deeper into classes, then the parent becomes the current class
currParentClass = currClass;
// If you go back out of a class
currParentClass = currClass.getParent();
}
}
// Traverse the hierarchy
public void traverse ()
{
traverseTree(root);
}
private void traverseTree (VMFClass root)
{
System.out.println("Class Name: " + root.getName());
// print out any properties
VMFProperty prop = root.getProperty();
if (prop != null)
{
System.out.println("Property Name: " + prop.getName());
String [] props = prop.getValues();
for (String s: props)
{
System.out.println("Value: " + s);
}
}
// get all child classes
List<VMFClass> children = root.getChildren();
for (VMFClass c: children)
{
traverseTree(c);
}
}
}
Client Code
Example
public static void main(String[] args)
{
VMFParser vmfParser = null;
try
{
vmfParser = new VMFParser("myFile.vmf");
vmfParser.parse();
// access the vmfParser for the hierarchy
vmfParser.traverse();
}
catch (VMFParsingException vpe)
{
// do something here
vpe.printStackTrace();
}
finally
{
// clean up...
}
}
If you are just looking to find all sub classes of particular class or interface , this might help you,
How can I get a list of all the implementations of an interface programmatically in Java?

How do I store information from methods to be used in another session?

So I'm making a program that will store the meetings I've had with some kids I'm tutoring. It'll keep tabs on the meeting times, discussions, and how many hours I've done. I know how to write all the methods to do that, but my issue is that the program will only hold that information for the session that the program is open... how would I go about storing this information and accessing it after the program is closed and opened again?
This is some excerpts from a test score keeper program I did in java class that has this same issue...
public class Student {
private String name;
private int test1;
private int test2;
private int test3;
public Student() {
name = "";
test1 = 0;
test2 = 0;
test3 = 0;
}
public Student(String nm, int t1, int t2, int t3){
name = nm;
test1 = t1;
test2 = t2;
test3 = t3;
}
public Student(Student s){
name = s.name;
test1 = s.test1;
test2 = s.test2;
test3 = s.test3;
}
public void setName(String nm){
name = nm;
}
public String getName (){
return name;
}
public void setScore (int i, int score){
if (i == 1) test1 = score;
else if (i == 2) test2 = score;
else test3 = score;
}
public int getScore (int i){
if (i == 1) return test1;
else if (i == 2) return test2;
else return test3;
}
public int getAverage(){
int average;
average = (int) Math.round((test1 + test2 + test3) / 3.0);
return average;
}
public int getHighScore(){
int highScore;
highScore = test1;
if (test2 > highScore) highScore = test2;
if (test3 > highScore) highScore = test3;
return highScore;
}
public String toString(){
String str;
str = "Name: " + name + "\n" + //\n makes a newline
"Test 1: " + test1 + "\n" +
"Test 2: " + test2 + "\n" +
"Test 3: " + test3 + "\n" +
"Average: " + getAverage();
return str;
}
}
If your data is not too big or complicated - something that you could save in a Rolodex in days gone by - you can save it to a file. Add methods to your class that will format the data properly and write it to a given OutputStream or Writer or whatever. And a method that will read it back.
To write to the file, add an option "save" in your program menu, and when it's chosen, open a file, iterate through your data, and call the saving method for each of your object.
To read from the file, add an option "load" in your program menu, and when it's chosen, open a file, and use your method of reading for each object.
The method for reading can be a static method in the class, that will first see if there are any data in the file and if it can read them properly, and only if it did, will create an object and return it (otherwise return null). There are other options, but this is the one that most encapsulates the needs of the object.
There is also an option to serialize and deserialize each object and put it in an object stream.
If the data is complicated, and there are many objects with various relations between them, you should use a database. This will require learning some database design and SQL.
To demonstrate the file reading/writing idea, add to your Student class:
public void save(PrintWriter outfile) {
outfile.format("%s|%d|%d|%d%n", name, test1, test2, test3);
}
This will write a line with the fields separated by "|" (vertical bar). Of course, you'll have to make sure none of the student names has a vertical bar in it. So you'll need to modify your 4-parameter constructor and your setter:
public Student(String nm, int t1, int t2, int t3) {
name = nm.replaceAll("\\|", "");
test1 = t1;
test2 = t2;
test3 = t3;
}
public void setName(String nm) {
name = nm.replaceAll("\\|", "");
}
Now, to read the file, we add a static method:
public static Student load(BufferedReader infile) throws IOException {
String line;
line = infile.readLine();
// Check if we reached end of file
if (line == null) {
return null;
}
// Split the fields by the "|", and check that we have no less than 4
// fields.
String[] fields = line.split("\\|");
if (fields.length < 4) {
return null;
}
// Parse the test scores
int[] tests = new int[3];
for (int i = 0; i < 3; i++) {
try {
tests[i] = Integer.parseInt(fields[i + 1]);
} catch (NumberFormatException e) {
// The field is not a number. Return null as we cannot parse
// this line.
return null;
}
}
// All checks done, data ready, create a new student record and return
// it
return new Student(fields[0], tests[0], tests[1], tests[2]);
}
You can see that this is more complicated, because you need to check that everything is OK at every step. In any case when things are not OK, we return null but of course, you can decide to just display a warning and read the next line. You'll have to return null when there are no more lines, though.
So, assuming we have a List<Student> students, here is how we write it to a file. I just chose "students.txt" but you can specify a full path leading where you want it. Note how I'm making a backup of the old file before I open the new file. If something goes wrong, at least you have the previous version of the file.
File f = new File("students.txt");
if (f.exists()) {
File backup = new File("students.bak");
if ( ! f.renameTo(backup) ) {
System.err.println( "Could not create backup.");
return;
}
f = new File("students.txt");
}
try ( PrintWriter outFile = new PrintWriter(f);) {
for (Student student : students) {
student.save(outFile);
}
} catch (FileNotFoundException e) {
System.err.println("Could not open file for writing.");
return;
}
After you do this, if you look for the file "students.txt", you will see the records you wrote in it.
How about reading it? Assume we have an empty students list (not null!):
try ( BufferedReader inFile = new BufferedReader(new FileReader(f))) {
Student student;
while ( ( student = Student.load(inFile)) != null) {
students.add(student);
}
} catch (FileNotFoundException e) {
System.err.println( "Could not open file for reading.");
return;
} catch (IOException e) {
System.err.println( "An error occured while reading from the file.");
}
Having done this, you can check your students list, and unless there were errors in the file, all your records will be there.
This is a demonstration, of course. You may want to read into some other collection or instead of printing an error and returning do something else. But it should give you the idea.
You could use db4o for persisting your data. Its an object-database with a spimple api to use. You can store java object read or delete them..
Download it here DB4O
And use the snippets of this tutorial (GER):Tutorial in German
Here is an example:
and Code:
package db4o.example;
public class Student {
String name;
public Student(String name) {
this.name = name;
}
#Override
public String toString() {
return "Student Name: " + name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package db4o.example;
import java.util.List;
import com.db4o.Db4oEmbedded;
import com.db4o.ObjectContainer;
public class Main {
public static void main(String[] args) {
ObjectContainer db = Db4oEmbedded.openFile("F:\\studentDB");
saveExample(db);
readAllExample(db);
readExample(db);
deleteAllExample(db);
db.close();
}
private static void deleteAllExample(ObjectContainer db) {
System.out.println("DeleteAllExample Example:");
List<Student> allStudents =readAllExample(db);
for (Student student : allStudents) {
db.delete(student);
}
db.commit();
}
private static List<Student> readAllExample(ObjectContainer db) {
System.out.println("ReadAllExample Example:");
List<Student> allStudents = db.query(Student.class);
System.out.println("Count: " + allStudents.size());
for (Student student : allStudents) {
System.out.println(student);
}
return allStudents;
}
private static void readExample(ObjectContainer db) {
System.out.println("ReadExample Example:");
Student queryStudent = new Student("Max Mustermann");
// Gets all Students named Max Mustermann
List<Student> students = db.queryByExample(queryStudent);
System.out.println("Count: " + students.size());
for (Student student : students) {
System.out.println(student);
}
}
private static void saveExample(ObjectContainer db) {
System.out.println("Save Example:");
Student myStudent = new Student("Max Mustermann");
db.store(myStudent);
db.commit();
}
}

Java: How to retrieve data from a control statement?

I'm creating an employee time clock for a java class. This portion of my program is for reporting an individual's time, and reporting all employees time. My code works well for the individual, but I'm having trouble converting it to work for all employees. Should I try looping through the whole file and retrieving as it goes? The information being inside a control statement is causing me problems. Also, to only look at a two-week period, would using calendar and date -14 days be a good way to accomplish that?
Any feedback on how to proceed appreciated.
package PunchinPunchout;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Scanner;
public class IDchecker {
private static BufferedReader br;
private static BufferedReader br1;
static int total;
static int total1;
public static void main(String args[]) throws IOException {
getsubject();
}
public static void getsubject() throws FileNotFoundException, IOException {
ArrayList<Integer> totalhours = new ArrayList<>();
br = new BufferedReader(new FileReader("timeclock1.txt"));
br1 = new BufferedReader(new FileReader("newemployee8.txt"));
String line = "";
String line1 = "";
Scanner sc = new Scanner(System.in);
System.out.print("Enter an employee ID number: ");
String idnumber = sc.next();//read the choice
sc.nextLine();// discard any other data entered on the line
while ((line1 = br1.readLine()) != null) {
if (line1.contains(idnumber)) {
System.out.println("Employee Name & ID ");
System.out.println(line1);
}
}
while ((line = br.readLine()) != null) {
if (line.contains(idnumber + " ") && line.contains("in")) {
System.out.println();
System.out.println(" Date Time ID Punched");
System.out.println(line);
String regexp = "[\\s:\\n]+"; // these are my delimiters
String[] tokens; // here i will save tokens
for (int i = 0; i < 1; i++) {
tokens = line.split(regexp);
total = Integer.parseInt(tokens[1]);
}
} else if (line.contains(idnumber + " ") && line.contains("out")) {
System.out.println(line);
String regexp = "[\\s:\\n]+";
String[] tokens;
for (int i = 0; i < 1; i++) {
tokens = line.split(regexp);
total1 = Integer.parseInt(tokens[1]);
System.out.print("Total hours for " + tokens[0] + " are: ");
}
int dailytotal = total1 - total;
System.out.println(dailytotal + " hours");
totalhours.add(dailytotal);
}
}
System.out.println();
int sum = totalhours.stream().mapToInt(Integer::intValue).sum();
System.out.println("The total hours for the last two weeks is " + sum + " hours.");
}
}
*Output from timeclock1.txt
05/05/2014 05:00:00 508 in
05/05/2014 09:00:00 508 out
05/05/2014 03:00:00 509 in
05/05/2014 09:00:00 509 out
05/05/2014 03:00:00 510 in
05/05/2014 08:00:00 510 out
05/05/2014 08:00:00 511 in
05/05/2014 10:00:00 511 out
*Output from newemployee8.txt
james bush 10
bobby bush 11
john hunt 12
mick jag 13
jacob sanchez 14
Okay, this a little of an over the top example, but it highlights the power of a OO language like Java...
There are a number of ways that this might be achieved, based on your requirements. I've made a few assumptions (like a in is followed by an out for the same employee), but the basic gist is demonstrated.
The intention is centralise some of the functionality into re-usable and manageable blocks, reducing the code duplication. Access to the data is simplified and because it's done in memory, is faster...
To start with, you will want to create object representations of the employee and time clock data, this will make it easier to manager...
Employee Example
public class Employee {
private final int id;
private final String name;
public Employee(String text) {
String[] parts = text.split(" ");
id = Integer.parseInt(parts[2]);
name = parts[0] + " " + parts[1];
}
public String getName() {
return name;
}
public int getId() {
return id;
}
}
TimeClockEntry example
public class TimeClockEntry {
private Date inTime;
private Date outTime;
private int employeeID;
public TimeClockEntry(String text) throws ParseException {
String parts[] = text.split(" ");
employeeID = Integer.parseInt(parts[2]);
setClockTimeFrom(text);
}
public void setClockTimeFrom(String text) throws ParseException {
String parts[] = text.split(" ");
if ("in".equalsIgnoreCase(parts[3])) {
inTime = CLOCK_DATE_TIME_FORMAT.parse(parts[0] + " " + parts[1]);
} else if ("out".equalsIgnoreCase(parts[3])) {
outTime = CLOCK_DATE_TIME_FORMAT.parse(parts[0] + " " + parts[1]);
}
}
public int getEmployeeID() {
return employeeID;
}
public Date getInTime() {
return inTime;
}
public Date getOutTime() {
return outTime;
}
}
Now, we need some kind of "manager" to manage the details of these two classes, these managers should provide access methods which allow use to retrieve information that they manage. These managers will also be responsible for loading the data from the files...
EmployeeManager example
public class EmployeeManager {
private Map<Integer, Employee> employees;
public EmployeeManager() throws IOException {
employees = new HashMap<>(25);
try (BufferedReader br = new BufferedReader(new FileReader(new File("NewEmployee8.txt")))) {
String text = null;
while ((text = br.readLine()) != null) {
Employee emp = new Employee(text);
employees.put(emp.getId(), emp);
}
}
}
public List<Employee> getEmployees() {
return Collections.unmodifiableList(new ArrayList<Employee>(employees.values()));
}
public Employee getEmployee(int id) {
return employees.get(id);
}
}
TimeClockManager example
public class TimeClockManager {
private Map<Integer, List<TimeClockEntry>> timeClockEntries;
public TimeClockManager() throws IOException, ParseException {
timeClockEntries = new HashMap<>(25);
try (BufferedReader br = new BufferedReader(new FileReader(new File("TimeClock1.txt")))) {
String text = null;
TimeClockEntry entry = null;
int line = 0;
while ((text = br.readLine()) != null) {
if (line % 2 == 0) {
entry = new TimeClockEntry(text);
} else {
entry.setClockTimeFrom(text);
List<TimeClockEntry> empEntries = timeClockEntries.get(entry.getEmployeeID());
if (empEntries == null) {
empEntries = new ArrayList<>(25);
timeClockEntries.put(entry.getEmployeeID(), empEntries);
}
empEntries.add(entry);
}
line++;
}
}
}
public List<TimeClockEntry> getByEmployee(Employee emp) {
List<TimeClockEntry> list = timeClockEntries.get(emp.getId());
list = list == null ? new ArrayList<>() : list;
return Collections.unmodifiableList(list);
}
}
Now, internally, these managers are managing the data through the use of Maps, to make it easier to find data, specifically, this is most keyed on the employee's id
Now, once we have these, we can ask for information from the as we please...
public Report() {
try {
EmployeeManager empManager = new EmployeeManager();
TimeClockManager timeClockManager = new TimeClockManager();
for (Employee emp : empManager.getEmployees()) {
System.out.println("[" + emp.getId() + "] " + emp.getName());
for (TimeClockEntry tce : timeClockManager.getByEmployee(emp)) {
System.out.println(" "
+ CLOCK_DATE_TIME_FORMAT.format(tce.getInTime())
+ " to "
+ CLOCK_DATE_TIME_FORMAT.format(tce.getOutTime()));
}
}
} catch (IOException | ParseException exp) {
exp.printStackTrace();
}
}
Another approach would be to incorporate both managers into a single class. The basic idea would be to load the employee and time clock data, the time clock data would become a property of the Employee and you could simply be able to access it directly.
This is a slightly more elegant solution, as you have all the data contained within a single construct, but might not meet your needs
Fully runnable example
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import oracle.jrockit.jfr.parser.ParseException;
public class Report {
public static void main(String[] args) {
new Report();
}
public Report() {
try {
EmployeeManager empManager = new EmployeeManager();
TimeClockManager timeClockManager = new TimeClockManager();
for (Employee emp : empManager.getEmployees()) {
System.out.println("[" + emp.getId() + "] " + emp.getName());
for (TimeClockEntry tce : timeClockManager.getByEmployee(emp)) {
System.out.println(" "
+ CLOCK_DATE_TIME_FORMAT.format(tce.getInTime())
+ " to "
+ CLOCK_DATE_TIME_FORMAT.format(tce.getOutTime()));
}
}
} catch (IOException | ParseException exp) {
exp.printStackTrace();
}
}
public class EmployeeManager {
private Map<Integer, Employee> employees;
public EmployeeManager() throws IOException {
employees = new HashMap<>(25);
try (BufferedReader br = new BufferedReader(new FileReader(new File("NewEmployee8.txt")))) {
String text = null;
while ((text = br.readLine()) != null) {
if (!text.trim().isEmpty()) {
Employee emp = new Employee(text);
employees.put(emp.getId(), emp);
}
}
}
}
public List<Employee> getEmployees() {
return Collections.unmodifiableList(new ArrayList<Employee>(employees.values()));
}
public Employee getEmployee(int id) {
return employees.get(id);
}
}
public class TimeClockManager {
private Map<Integer, List<TimeClockEntry>> timeClockEntries;
public TimeClockManager() throws IOException, ParseException {
timeClockEntries = new HashMap<>(25);
try (BufferedReader br = new BufferedReader(new FileReader(new File("TimeClock1.txt")))) {
String text = null;
TimeClockEntry entry = null;
int line = 0;
while ((text = br.readLine()) != null) {
if (!text.trim().isEmpty()) {
if (line % 2 == 0) {
entry = new TimeClockEntry(text);
} else {
entry.setClockTimeFrom(text);
List<TimeClockEntry> empEntries = timeClockEntries.get(entry.getEmployeeID());
if (empEntries == null) {
empEntries = new ArrayList<>(25);
timeClockEntries.put(entry.getEmployeeID(), empEntries);
}
empEntries.add(entry);
}
line++;
}
}
}
}
public List<TimeClockEntry> getByEmployee(Employee emp) {
List<TimeClockEntry> list = timeClockEntries.get(emp.getId());
list = list == null ? new ArrayList<>() : list;
return Collections.unmodifiableList(list);
}
}
public class Employee {
private final int id;
private final String name;
public Employee(String text) {
System.out.println("[" + text + "]");
for (char c : text.toCharArray()) {
System.out.print((int) c + ",");
}
System.out.println("");
String[] parts = text.split("\\s+");
id = Integer.parseInt(parts[2]);
name = parts[0] + " " + parts[1];
}
public String getName() {
return name;
}
public int getId() {
return id;
}
}
public static final SimpleDateFormat CLOCK_DATE_TIME_FORMAT = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
public static final SimpleDateFormat CLOCK_DATE_FORMAT = new SimpleDateFormat("dd/MM/yyyy");
public class TimeClockEntry {
private Date inTime;
private Date outTime;
private int employeeID;
public TimeClockEntry(String text) throws ParseException {
System.out.println("[" + text + "]");
for (char c : text.toCharArray()) {
System.out.print((int) c + ",");
}
System.out.println("");
String parts[] = text.split("\\s+");
employeeID = Integer.parseInt(parts[2]);
setClockTimeFrom(text);
}
public void setClockTimeFrom(String text) throws ParseException {
String parts[] = text.split("\\s+");
if ("in".equalsIgnoreCase(parts[3])) {
inTime = CLOCK_DATE_TIME_FORMAT.parse(parts[0] + " " + parts[1]);
} else if ("out".equalsIgnoreCase(parts[3])) {
outTime = CLOCK_DATE_TIME_FORMAT.parse(parts[0] + " " + parts[1]);
}
}
public int getEmployeeID() {
return employeeID;
}
public Date getInTime() {
return inTime;
}
public Date getOutTime() {
return outTime;
}
}
}

Categories