group and sum sales in String array java - java

I have a text file as below:
Pen 100
Ink 50
Pen 150
Paper 20
and I want to sum each of the goods
the output should look like:
Pen 250
Ink 50
Paper 20
Max Pen 250
Min Paper 20
I write just only some code below and I stuck:
public static void readData(){
File infile = new File("D:\\itemData.txt");
String itemName = new String();
String[] nameList = new String[100];
String[] saleList = new String[100];
int sale;
int count =0;
try {
Scanner data = new Scanner(infile);
while (data.hasNext()) {
itemName = data.next();
sale = data.nextInt();
nameList[count] = name;
saleList[count] = String.valueOf(sale);
count++;
for (int i = 0; i < nameList.length; i++) {
if (nameList[i] != null) {
System.out.println(nameList[i] + " " + saleList[i]);
}
}
data.close();
}
} catch (IOException e) {
}}

Try the code below.
There were 2 issues in the code I could see.
a) You did not declare the variable count
b) You were printing while reading the data, and that is not desirable.
public static void readData(){
File infile = new File("D:\\itemData.txt");
String itemName = new String();
String[] nameList = new String[100];
String[] saleList = new String[100];
int sale;
int count = 0;
try {
Scanner data = new Scanner(infile);
while (data.hasNext()) {
itemName = data.next();
sale = data.nextInt();
nameList[count] = name;
saleList[count] = String.valueOf(sale);
count++;
data.close();
}
} catch (SIOException e) {
}
for (int i = 0; i < nameList.length; i++) {
if (nameList[i] != null) {
System.out.println(nameList[i] + " " + saleList[i]);
}
}
}

Also consider implementing something like this to keep track of maxes and mins for you:
package com.example.demo;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.collections4.map.HashedMap;
public class Inventory {
private Map<String, AtomicInteger> totals = new HashedMap<>();
private Map<String, AtomicInteger> maxes = new HashedMap<>();
private Map<String, AtomicInteger> mins = new HashedMap<>();
public void add(String name, int number) {
getOrCreateFromMap(totals, name, 0).addAndGet(number);
getOrCreateFromMap(maxes, name, Integer.MIN_VALUE).getAndUpdate(present -> (present < number) ? number : present);
getOrCreateFromMap(mins, name, Integer.MAX_VALUE).getAndUpdate(present -> (number < present) ? number : present);
}
private AtomicInteger getOrCreateFromMap(Map<String, AtomicInteger> map, String name, int initialValue) {
return map.computeIfAbsent(name, x -> new AtomicInteger(initialValue));
}
public int getTotal(String name) {
return getFromMap(totals, name);
}
public int getMax(String name) {
return getFromMap(maxes, name);
}
public int getMin(String name) {
return getFromMap(mins, name);
}
private int getFromMap(Map<String, AtomicInteger> map, String key) {
return map.computeIfAbsent(key, x -> new AtomicInteger())
.get();
}
public static void main(String[] args) {
Inventory i = new Inventory();
i.add("paper", 50);
i.add("paper", 150);
System.out.println(i.getTotal("paper"));
System.out.println(i.getMax("paper"));
System.out.println(i.getMin("paper"));
}
}

Here is a working example, for the mentioned problem statement -
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Map;
import java.util.stream.Collectors;
public class ReadAndSumFileData {
public static void main(String... arguments) throws IOException {
String filename = "C:/temp/SalesData.txt";
readData(filename);
}
private static void readData(String filename) throws IOException {
Map<String, Integer> map = Files.lines(Paths.get(filename))
.map(s -> s.split("\\s+"))
.collect(Collectors.groupingBy(a -> a[0], Collectors.summingInt(a -> Integer.parseInt(a[1]))));
map.entrySet().stream().forEach(e-> System.out.println(e));
}
}

Related

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;
}
}

How to remove duplicate in list based on two custom objects

I have ProductDetail class which contains two variables productName and productVersion. I need to replace duplicate items in the list according to the latest productVersion.
Example:
class ProductDetails {
string productName;
string productVersion;
}
new ProductDetails("ios", "9.1.0")
new ProductDetails("android", "6.0.1")
new ProductDetails("android", "5.1.1")
new ProductDetails("ios", "10.0.0")
Result:
android 6.0.1
ios 10.0.0
Thanks in advance.
This should work out for you:
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
public class ProductDetails {
private String productName;
private String productVersion;
private List<ProductDetails> productData = null;
public ProductDetails(String productName,String productVersion){
this.productName = productName;
this.productVersion = productVersion;
if(productData == null) {
productData = new ArrayList<ProductDetails>();
adNewProduct(this);
}
}
private void adNewProduct(ProductDetails p){
String[] s1 = p.productVersion.split(Pattern.quote("."));
for (ProductDetails dpp: productData) {
if (dpp.productName.equals(p.productName)) {
int index = productData.indexOf(dpp);
String[] s2 = dpp.productVersion.split(Pattern.quote("."));
for(int i = 0; i < s1.length; i++) {
int v1 = Integer.valueOf(s1[i]);
int v2 = Integer.valueOf(s2[i]);
if (v1 > v2) {
productData.set(index,p);
return;
}
}
}
}
productData.add(p);
}
#Override // you can modify it to how you want
public String toString(){
String s = "";
for (ProductDetails p: productData){
s += "ProductName: " + p.productName + " ProductVersion: " + p.productVersion + "\n";
}
return s;
}
//the main method
public static void main(String[] args) {
ProductDetails k = new ProductDetails("ios", "9.1.1");
k.adNewProduct(new ProductDetails("android", "5.1.1"));
k.adNewProduct(new ProductDetails("android", "6.0.1"));
k.adNewProduct(new ProductDetails("ios", "10.0.0"));
System.out.println(k);
}
}
Output:
ProductName: ios ProductVersion: 10.0.0
ProductName: android ProductVersion: 6.0.1
You can put all those objects into a Map<String, ProductDetails> and keep the one with the latest version.
List<ProductDetails> details = Arrays.asList(
new ProductDetails("ios", "9.1.0"),
new ProductDetails("android", "6.0.1"),
new ProductDetails("android", "5.1.1"),
new ProductDetails("ios", "10.0.0"));
// get part of version string
Function<Integer, Function<ProductDetails, Integer>> version =
n -> (pd -> Integer.valueOf(pd.getProductVersion().split("\\.")[n]));
// chain to comparator
Comparator<ProductDetails> versionComp = Comparator.comparing(version.apply(0))
.thenComparing(version.apply(1)).thenComparing(version.apply(2));
Map<String, ProductDetails> latest = new HashMap<>();
for (ProductDetails pd : details) {
String name = pd.getProductName();
if (! latest.containsKey(name) || versionComp.compare(latest.get(name), pd) < 0) {
latest.put(name, pd);
}
}
Afterwards, latest is:
{android=Sandbox.ProductDetails(productName=android, productVersion=6.0.1),
ios=Sandbox.ProductDetails(productName=ios, productVersion=10.0.0)}
Or, you can use Collectors.groupingBy and then use the same Comparator:
details.stream()
.collect(Collectors.groupingBy(ProductDetails::getProductName))
.values().stream().map(list -> Collections.max(list, versionComp))
.forEach(System.out::println);

DoubleStream returning the value 0.0 when should be 136.0

In my program I am using a DoubleStreamto sum the values of an array.
I have the following code
Training P List
import java.io.*;
import java.util.*;
import java.lang.*;
import java.util.stream.DoubleStream;
public class TrainingPList
{
int aSize=500; // size of constant
TrainingP[] arrayTrainingP= new TrainingP[aSize]; // array name + aSize constant called to define size of the array
int nextPosition=0;// size of constant
double[] MoneyList;
public void readPersonal()
{
try
{
BufferedReader br=new BufferedReader(new FileReader("TrainingP.txt"));
String theNextPublicInfo = br.readLine();
nextPosition=0;
while (theNextPublicInfo !=null)
{
String[] arrayStringPersonalInfo = theNextPublicInfo.split(",");
TrainingP tempPInfo = new TrainingP();
tempPInfo.AthleteID = arrayStringPersonalInfo[0];
tempPInfo.rMoneyRaised = Double.parseDouble(arrayStringPersonalInfo[1]);
arrayTrainingP[nextPosition] = tempPInfo;
nextPosition++;
theNextPublicInfo = br.readLine();
}
}
catch(Exception e)
{
System.out.println("Invalid read data");
}
}
public void outputarrayTrainingP()
{
for(int i=0;i<nextPosition;i++)
{
System.out.println ("Position "+":"+arrayTrainingP[i]);
}
}
public void ListAth()
{
AthList = new String[nextPosition];
for(int i=0;i<nextPosition;i++)
{
AthList[i]=arrayTrainingP[i].AthleteID+"";
}
}
public void ListMoney()
{
MoneyList = new double[nextPosition];
for(int i=0;i<nextPosition;i++)
{
MoneyList[i]=arrayTrainingP[i].rMoneyRaised;
}
DoubleStream d = DoubleStream.of(MoneyList);
double dv = d.sum();
System.out.println("The sum is " + dv);
}
public static void main(String[] args)
{
TrainingPList tp = new TrainingPList();
tp.ListMoney();
tp.readPersonal();
tp.outputarrayTrainingP();
}
}
TrainingP
public class TrainingP
{
String AthleteID;
double rMoneyRaised;
public String toString()
{
return AthleteID+","+rMoneyRaised;
}
}
Document
DJ44,136.0
DB15,0.0
There are only two values for rMoneyRaised and they are 136.0 and 0.0. However it only returns 0.0 instead of the value 136.0. Does anyone know what the problem is?
There is a problem in the main method:
public static void main(String[] args)
{
TrainingPList tp = new TrainingPList();
tp.ListMoney();
tp.readPersonal();
tp.outputarrayTrainingP();
}
You should call tp.ListMoney() after reading in the data, not before.

Get preferences older than the most recent entry using java.util.prefs.Preferences.get

With the java.util.prefs.Preferences API is it possible to get historic results which are older than the last entry?
eg if you had
prefs.put("key", "value1");
prefs.put("key", "value2");
return prefs.get("key");
will return "value2"
Can I ever get "value1" ?
If no then what is the best alternative to achieve this functionality.
If anyone can do better I am happy to accept their answer, in the mean time:
import java.util.ArrayList;
import java.util.List;
import java.util.prefs.Preferences;
public class RecentStrings
{
private final Preferences prefs;
private final int noRecent;
private static final int defaultNo = 10;
private final String indexingKey;
public RecentStrings()
{
this(Preferences.userRoot(), defaultNo, "r");
}
public RecentStrings(Preferences prefs, int noRecent, String indexingKey)
{
this.noRecent = noRecent;
this.prefs = prefs;
this.indexingKey = indexingKey;
}
public void setMostRecentString(String file)
{
if (!getAllRecentStrings().contains(file))
{
for (int i = noRecent-1; i >= 0; i--)
{
prefs.put(indexingKey+(i+1), prefs.get(indexingKey+i, ""));
}
prefs.put(indexingKey+0, file);
}
else
{
removeRecentString(file);
setMostRecentString(file);
}
}
private void removeRecentString(String file)
{
List<String> recents = getAllRecentStrings();
recents.remove(file);
for (int i=0; i < noRecent; i++)
{
String value;
if (i < recents.size())
{
value = recents.get(i);
}
else
{
value = "";
}
prefs.put(indexingKey+i,value);
}
}
public String getMostRecentString()
{
return prefs.get(indexingKey+0, "");
}
public List<String> getAllRecentStrings()
{
List<String> mostRecent = new ArrayList<>();
for (int i = 0; i < 10; i++)
{
String value = prefs.get(indexingKey+i, "");
if (!value.equals(""))
{
mostRecent.add(value);
}
}
return mostRecent;
}
}
Which also handles duplicates and keeps things from most recent to oldest.

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