How to synchronize threads in java - java

I need to register the order of each customer
The waiter can only deliver orders after write down all requests of your customers.
Customer must wait until the request is delivered
I can not synchronize the client actions with the waiter
I need synchronize each action from my objects Customer and Waiter
Customer has 1 order
Waiter has N customers
The sequence of actions to be synchronized was implemented in the "run" method of each thread
package room;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Customer extends Thread {
private Random random;
private int id;
private static int ID;
private Order order;
private Waiter waiter;
public Customer(Waiter garcom) {
this.random = new Random();
this.id = ID + 1;
Customer.ID++;
this.waiter = garcom;
}
#Override
public void run() {
orderRequest();
waitOrder();
receiveRequest();
consumer();
}
public synchronized void orderRequest() {
synchronized (this.order) {
int r = random.nextInt(3);
switch (r) {
case 0:
this.order.setOrder("Food");
break;
case 1:
this.order.setOrder("Drink");
break;
default:
this.order.setOrder("Help");
break;
}
System.out.println(this.toString() + " request " + this.order.getOrder() + "to " + this.waiter.toString());
this.order.notify();
try {
this.order.wait();
} catch (InterruptedException ex) {
Logger.getLogger(Customer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public synchronized void receiveRequest() {
synchronized (this.order) {
this.order.notify();
try {
this.order.wait();
} catch (InterruptedException ex) {
Logger.getLogger(Customer.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(this + " has received " + this.order + " from " + this.waiter);
}
}
private void waitOrder() {
synchronized (this.order) {
System.out.println(this + " consumer " + this.order);
this.order.notify();
try {
this.order.wait();
} catch (InterruptedException ex) {
Logger.getLogger(Customer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public synchronized void consumer() {
synchronized (this.order) {
System.out.println(this + " was consumed " + this.order);
this.order.notify();
try {
this.order.wait();
} catch (InterruptedException ex) {
Logger.getLogger(Customer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public void setOrder(Order order) {
this.order = order;
}
public Order getOrder() {
return order;
}
#Override
public String toString() {
return "Customer: " + id;
}
}
package room;
public class Order {
private int orderNumber;
private static int ORDER_NUMBER = 0;
private Customer customer;
private String order;
public Order(Customer c) {
this.customer = c;
this.orderNumber = ORDER_NUMBER + 1;
this.customer.setOrder(this);
Order.ORDER_NUMBER++;
}
public String getOrder() {
return order;
}
public int getOrderNumber() {
return orderNumber;
}
public void setOrder(String order) {
this.order = order;
}
public Customer getCustomer() {
return customer;
}
#Override
public String toString() {
return "Order: " + order + " Nº " + orderNumber;
}
}
package room;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Waiter extends Thread {
private Saloon saloon;
private int id;
private static int ID = 0;
private List<Order> orders;
public Waiter(Saloon bar) {
this.saloon = bar;
this.id = ID + 1;
Waiter.ID++;
this.orders = new ArrayList<>();
}
#Override
public void run() {
while (saloon.isOpen()) {
registerOrder();
deliveryRequest();
saloon.round();
}
}
public synchronized void registerOrder() {
for (Order order : orders) {
synchronized (order) {
order.notify();
try {
order.wait();
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
System.out.println(this.toString() + " "
+ "record " + order.toString()
+ " to " + order.getCustomer());
}
}
}
public synchronized void deliveryRequest() {
for (Order order : orders) {
synchronized (order) {
order.notify();
try {
order.wait();
} catch (InterruptedException ex) {
Logger.getLogger(Waiter.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(this.toString() + " "
+ "delivered " + order.toString()
+ " to " + order.getCustomer());
}
}
}
public synchronized void recordOrder(Order order) {
synchronized (orders) {
this.orders.add(order);
}
}
public List<Order> getOrders() {
return orders;
}
public Saloon getSaloon() {
return saloon;
}
#Override
public String toString() {
return "Waiter: " + id;
}
}
package room;
import java.util.ArrayList;
import java.util.List;
public class Saloon {
private int maxRound;
private int numGarcons;
private volatile int round;
private int capacity;
private int customerCount;
private final List<Waiter> waiters;
public Saloon() {
this.waiters = new ArrayList<>();
this.round = 1;
}
public Saloon(int customerCount, int waiterCount,
int capacity, int rounds) {
this();
this.numGarcons = waiterCount;
this.customerCount = customerCount;
this.capacity = capacity;
this.maxRound = rounds;
}
/**
* Should it be call each round
*/
public void openBar() {
this.capacity = this.customerCount / this.capacity;
System.out.println("Round " + this.round);
for (int i = 0; i < this.numGarcons; i++) {
//Create a waiter
Waiter g = new Waiter(this);
for (int j = 0; j < this.capacity; j++) {
//create customer
Customer c = new Customer(g);
//an order
Order p = new Order(c);
//register order
g.recordOrder(p);
//call thread client
c.start();
}
//waiter serves one client at a time
g.start();
this.waiters.add(g);
}
}
public boolean isOpen() {
if (this.round < this.maxRound) {
return true;
}
return false;
}
public void round() {
this.round++;
}
}

Okay I must say I enjoyed the challenge... But I have figured this out. I should note that I attempted your original maxRounds and though it works there is a bug where 1 extra customer can make it through the queue. NOTE: I am do not claim this is the absolute best way to do this... nor necessarily the most elegant but it should point you towards the right direction.
I would suggest reading about BlockingQueues and classes the extend it.
Main call to the saloon:
public static void main(String[] args) {
Saloon saloon = new Saloon(100, 4, 50);
saloon.openBar();
}
Saloon Class:
package room;
import java.util.ArrayList;
import java.util.List;
public class Saloon {
private volatile static int round;
private static int maxRound;
private int numWaiters;
private final List<Waiter> waiters;
private int customerMax; // current implementation doesn't need this but you could if you wanted
private volatile static boolean isOpen;
private OrderQueue<Order> orderQueue; // This is the creation of the queue
public Saloon() {
this.waiters = new ArrayList<>();
Saloon.round = 1;
}
public Saloon(int customerMax, int numWaiters, int maxRounds) {
this();
this.customerMax = customerMax;
this.numWaiters = numWaiters;
this.orderQueue = new OrderQueue<Order>(numWaiters);
Saloon.maxRound = maxRounds;
}
/**
* Should it be call each round
*/
public void openBar() {
System.out.println("Round " + round);
isOpen = true;
// Create all waiters at once outside the loop
for (int i = 0; i < this.numWaiters; i++) {
waiters.add(new Waiter(i + 1, orderQueue));
waiters.get(i).start();
}
int customersServed = 1; // Generating the id number here is a better choice IMO
while(isOpen) {
for (Waiter waiter : waiters) {
if (round >= maxRound) {
closeBar();
}
if (waiter.isAvailable() && !waiter.isClockedOut()) {
// create customer
Customer customer = new Customer(customersServed++, waiter, orderQueue);
customer.start();
}
}
}
}
/**
* A simple implementation to close the bar
*/
public void closeBar() {
isOpen = false; // ends the loop
int waitersFinished = 0; // used to check if all waiters stopped serving
while (waitersFinished < numWaiters) {
for (Waiter waiter : waiters) {
if (waiter.isAvailable()) {
synchronized (orderQueue) {
// if nothing is currently in the queue for the waiters
if (orderQueue.isEmpty()) {
orderQueue.done(); // close the queue
orderQueue.notify(); // notify the queue
}
waiter.clockOut(); // clockout the waiter could use better implementation
waitersFinished++; // increment waiters finished
}
}
}
}
}
public static boolean isOpen() {
return isOpen;
}
// I would not recommend using this... this is the source of the glitch
public synchronized static void round() {
if (round <= maxRound) { // only if reached maxRounds
System.out.println("Round " + round);
round++;
}
}
}
OrderQueue Class:
package room;
import java.util.concurrent.ArrayBlockingQueue;
/**
*
* Note I did not create this.. tomasb did and I implemented it.
*
* #param <T>
*/
public class OrderQueue<T> extends ArrayBlockingQueue<T> {
private static final long serialVersionUID = 1L;
private boolean done = false;
/**
* creates an order queue with a max capacity.. orders that can be concurrently handled
* #param capacity
*/
public OrderQueue(int capacity) {
super(capacity);
}
/**
* closes the while loop ending this orderqueue
*/
public void done() {
done = true;
}
public boolean isDone() {
return done;
}
/**
* May return null if producer ends the production after consumer has
* entered the element-await state.
*/
public T take() throws InterruptedException {
T el;
while ((el = super.poll()) == null && !done) {
synchronized (this) {
wait();
}
}
return el;
}
}
Order Class:
package room;
public class Order {
private int orderNumber;
private static int ORDER_NUMBER = 0;
private String order;
public Order(int orderNumber) {
this.orderNumber = ORDER_NUMBER + 1;
this.orderNumber = orderNumber;
}
public String getOrder() {
return order;
}
public int getOrderNumber() {
return orderNumber;
}
public void setOrder(String order) {
this.order = order;
}
#Override
public String toString() {
return "Order: " + order + " Nº " + orderNumber;
}
}
Customer Class:
package room;
import java.util.Random;
public class Customer extends Thread {
private int id;
private int orderNumber = 1;
private Order order;
private Waiter waiter;
private OrderQueue<Order> orderQueue; // This provides an esay way to pass objects
public Customer(int id, Waiter waiter, OrderQueue<Order> orderQueue) {
this.id = id;
this.waiter = waiter;
this.orderQueue = orderQueue;
waiter.addCustomer(this);
System.out.println("Customer: " + id + " sat at a table!");
}
#Override
public void run() {
// Notice that wait has been removed. The orderQueue takes care of this.
orderRequest();
receiveRequest();
consumer();
System.out.println("Customer: " + id + " has left satisfied!");
}
public void orderRequest() {
// none of thie should be synchronized as it is local
order = new Order(orderNumber++);
Random random = new Random();
int r = random.nextInt(3);
switch (r) {
case 0:
order.setOrder("Food");
break;
case 1:
order.setOrder("Drink");
break;
default:
order.setOrder("Help");
break;
}
System.out.println(this.toString() + " request " + order.getOrder() + " to " + this.waiter.toString());
// only the call to the orderqueue is synchronized
try {
synchronized (orderQueue) {
orderQueue.put(order);
orderQueue.notify();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void receiveRequest() {
System.out.println(this + " has received " + this.order + " from " + this.waiter);
}
public void consumer() {
System.out.println(this + " was consumed " + this.order);
}
#Override
public String toString() {
return "Customer: " + id;
}
}
And finally the Waiter Class:
package room;
public class Waiter extends Thread {
private int id;
private Order custOrder;
private Customer customer;
private volatile boolean isAvailable;
private volatile boolean clockOut;
private OrderQueue<Order> orderQueue; // The queue again
public Waiter(int id, OrderQueue<Order> orderQueue) {
this.id = id;
this.orderQueue = orderQueue;
System.out.println("Waiter " + id + " is ready to serve!");
}
#Override
public void run() {
isAvailable = true;
while (!orderQueue.isDone() && !clockOut) {
if (isAvailable) { // this waiter is ready for a task
registerOrder();
isAvailable = false;
synchronized (orderQueue) { // Synchronize this to the queue to prevent worse glitches
Saloon.round();
}
if (custOrder != null) { // error checking
System.out.println(this.toString() + " record " + custOrder.toString() + " to " + customer);
deliveryRequest();
} else {
isAvailable = true;
}
}
}
}
public synchronized void registerOrder() {
try {
custOrder = orderQueue.take(); // this is how you pull the order
} catch (InterruptedException e1) {
System.out.println(true);
}
}
public synchronized void deliveryRequest() {
System.out.println(this.toString() + " " + "delivered " + custOrder.toString() + " to " + customer);
isAvailable = true;
}
public void addCustomer(Customer customer) { // a easy way to add customers to the waiter after creation
this.customer = customer;
isAvailable = false;
}
public Order getOrder() {
return custOrder;
}
#Override
public String toString() {
return "Waiter: " + id;
}
public boolean isAvailable() {
return isAvailable;
}
public void clockOut() {
clockOut = true;
}
public boolean isClockedOut() {
return clockOut;
}
}

Related

Summing up an ArrayList with multiple types

I am having trouble summing up my ArrayList that I made in my class Treasureroom which is in my class Accountant. I have an ArrayList with type Valuable as you can see in the code below. I need to be able to sum up all the int elements from within the Accountant class.
Accountant
package Accountant;
import java.util.Iterator;
import java.util.Random;
import ValuableFactory.Valuable;
import rw.RWMonitor;
import rw.Treasureroom;
public class Accountant implements Runnable {
private Treasureroom treasureroom;
private static final int MAX_WAIT_TIME = 10000; // 3 seconds
private static final int MAX_WORK_TIME = 5000; // 2 seconds
private static final Random random = new Random();
private int no;
private RWMonitor monitor;
private Treasureroom resource;
public Accountant( int no, RWMonitor monitor, Treasureroom resource ) {
this.no = no;
this.monitor = monitor;
this.resource = resource;
}
public void run() {
while(true) {
try {
Thread.sleep(random.nextInt(WAIT_TIME));
}
catch (InterruptedException ex) {
}
System.out.println("Accountant counts: " + resource);
monitor.acquireRead();
//System.out.println("Accountant counted: " + valuable);
try {
Thread.sleep(random.nextInt(MAX_WAIT_TIME));
}
catch (InterruptedException ex) {
}
for (int i = 0; i > resource.)
System.out.println("Accountant counted: " + resource.getValueRead());
monitor.releaseRead();
try {
Thread.sleep(random.nextInt(WAIT_AGAIN));
}
catch (InterruptedException ex) {
// TODO: handle exception
}
}
}
//System.out.println("The total sum of TreasureRoom is " + Thread.currentThread().getName());
//TreasureRoom.releaseRead();
}
Treasureroom
package rw;
import java.util.*;
import ValuableFactory.*;
public class Treasureroom {
ArrayList<Valuable> valuables = new ArrayList<Valuable>();
public Valuable getValueWriter() {
return valuables.remove(0);
}
public void updateValue(Valuable valuable) {
valuables.add(valuable);
}
public boolean removeValue(Valuable valuable) {
return valuables.remove(valuable);
}
public Valuable getValueReade() {
for (int i=0; i<valuables.size();i++) {
return valuables.get(i);
}
return null;
}
}
Valuable
package ValuableFactory;
public class Valuable implements ValuableFactory {
private String name;
private int value;
public Valuable(String name, int value) {
this.name = name;
this.value = value;
}
#Override
public String getName() {
return name;
}
#Override
public int getValue() {
return value;
}
}
Your Accountant class instantiates your Treasureroom object in its constructor, meaning that to loop through the ArrayList inside the Treasureroom object using an Accountant object you would need a method in Accountant that calls a method in Treasureroom.
Accountant
public int getTreasureSum()
{
return resource.sumTreasure();
}
Treasureroom
public int sumTreasure()
{
int sum = 0;
for(int i = 0; i < valuables.size(); i++)
{
sum+= valuables.get(i).getValue();
}
return sum;
}
Also in your Accountant class you have an unused Treasureroom object
private Treasureroom treasureroom;

Using CSV premier league match data to update an object value java and return to CSV

I am new to Java and I am attempting to manipulate some football match data in order to get a more in-depth understanding of the results. I have managed to get it to read from the CSV and I can get the individual values. The CSV format is like this fopr about 400 rows:
Arsenal,Leicester,4,3,H
Brighton,Man City,0,2,A
Chelsea,Burnley,2,3,A
Crystal Palace,Huddersfield,0,3,A
Everton,Stoke,1,0,H
Southampton,Swansea,0,0,D
What I have struggled with is to retrieve the home team and away teams(objects and unsure how to match the string from the CSV to them): current points, league position goal, difference along with the match in a row in excel (I plan to use an artificial neural network to predict matches from this data) then I would like to match and update the correct object of each team e.g.if home team is Arsenal and they win 2-0 update Team Arsenal() to have 3 more points, 2 more goals scored, update league table position. Once this is done it will read the next result and repeat.
I know this is a lot but I am really struggling on these parts so would really appreciate some help for a newbie to java.
Here is my current code:
InputHere.java:
package BasicP;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
public class InputHere {
public static void main(String[] args) {
List<Match> matches = new ArrayList<>();
Path logFile = Paths.get("C:\\Users\\Lewys\\Documents", "FinalofFootballDataws.csv");
try (BufferedReader read
= Files.newBufferedReader(logFile, StandardCharsets.US_ASCII)) {
String firstLine = read.readLine();
while (firstLine != null) {
String[] variables = firstLine.split(",");
String homeName = variables[0];
String awayName = variables[1];
String strHomeScore = variables[2];
String strAwayScore = variables[3];
int homeScore = Integer.parseInt(strHomeScore);
int awayScore = Integer.parseInt(strAwayScore);
firstLine = read.readLine();
}
} catch(IOException ioe) {
ioe.printStackTrace();
}
return;
}
}
Team.java:
public class Team {
private String teamName;
private int numberWin;
private int numberDraw;
private int numberLoss;
private int matchesPlayed;
private int points;
private int goalsScored;
private int goalsConceded;
private int tablePosition;
public Team(String teamName, int numberWin, int numberDraw,
int numberLoss, int matchesPlayed, int points,
int goalsScored, int goalsConceded, int tablePosition) {
}
public int getNumberWin() {
return numberWin;
}
public int getNumberDraw() {
return numberDraw;
}
public int getNumberLoss() {
return numberLoss;
}
public int getMatchesPlayed() {
return matchesPlayed;
}
public int getPoints() {
return points;
}
public int getGoalsScored() {
return goalsScored;
}
public int getGoalsConceded() {
return goalsConceded;
}
public int getTablePosition() {
return tablePosition;
}
public void setNumberWin(int i) {
numberWin = numberWin + i;
}
public void setNumberDraw(int i) {
numberDraw = numberDraw + i;
}
public void setNumberLoss(int i) {
numberLoss = numberLoss + i;
}
public void setMatchesPlayed(int i) {
matchesPlayed = matchesPlayed + i;
}
public void setPoints(int i) {
points = points + i;
}
public void setGoalsScored(int i) {
goalsScored = goalsScored + i;
}
public void setGoalsConceded(int i) {
goalsConceded = goalsConceded + i;
}
public void settablePosition(int i) {
tablePosition = i;
}
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
}
I try solve your issue.
Firt a write a CSVReader, but I suggest you to try using a specific library for it to better manage all csv format.
public class FootballMatchCSVReader {
public List<FootballMatch> read(String filePath) throws IOException {
return readAllLines(filePath).stream().map(line -> mapToFootballMatch(line.split(","))).collect(toList());
}
private List<String> readAllLines(String filePath) throws IOException {
return Files.readAllLines(Paths.get(filePath));
}
private FootballMatch mapToFootballMatch(String[] args) {
return new FootballMatch(args[0],args[1],Integer.valueOf(args[2]),Integer.valueOf(args[3]),args[4].charAt(0));
}
}
That return a List of FootballMatch
public class FootballMatch {
private String homeTeam;
private String awayTeam;
private int homeTeamScore;
private int awayTeamScore;
private char finalResult;
public FootballMatch(String homeTeam, String awayTeam, int homeTeamScore, int awayTeamScore, char winner) {
this.homeTeam = homeTeam;
this.awayTeam = awayTeam;
this.homeTeamScore = homeTeamScore;
this.awayTeamScore = awayTeamScore;
this.finalResult = winner;
}
public String getHomeTeam() {
return homeTeam;
}
public void setHomeTeam(String homeTeam) {
this.homeTeam = homeTeam;
}
public String getAwayTeam() {
return awayTeam;
}
public void setAwayTeam(String awayTeam) {
this.awayTeam = awayTeam;
}
public int getHomeTeamScore() {
return homeTeamScore;
}
public void setHomeTeamScore(int homeTeamScore) {
this.homeTeamScore = homeTeamScore;
}
public int getAwayTeamScore() {
return awayTeamScore;
}
public void setAwayTeamScore(int awayTeamScore) {
this.awayTeamScore = awayTeamScore;
}
public char getFinalResult() {
return finalResult;
}
public void setFinalResult(char finalResult) {
this.finalResult = finalResult;
}
#Override
public String toString() {
return "FootballMatch{" +
"homeTeam='" + homeTeam + '\'' +
", awayTeam='" + awayTeam + '\'' +
", homeTeamScore=" + homeTeamScore +
", awayTeamScore=" + awayTeamScore +
", finalResult=" + finalResult +
'}';
}
}
Now I write a FootballMatchStatisticsEngine that compute the TeamStatistic for each match
public class TeamStatistic {
private String teamName;
private int numberWin;
private int numberDraw;
private int numberLoss;
private int matchesPlayed;
private int points;
private int goalsScored;
private int goalsConceded;
private int tablePosition;
public TeamStatistic(String teamName, int numberWin, int numberDraw, int numberLoss, int matchesPlayed, int points, int goalsScored, int goalsConceded, int tablePosition) {
this.teamName = teamName;
this.numberWin = numberWin;
this.numberDraw = numberDraw;
this.numberLoss = numberLoss;
this.matchesPlayed = matchesPlayed;
this.points = points;
this.goalsScored = goalsScored;
this.goalsConceded = goalsConceded;
this.tablePosition = tablePosition;
}
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
public int getNumberWin() {
return numberWin;
}
public void setNumberWin(int numberWin) {
this.numberWin = numberWin;
}
public int getNumberDraw() {
return numberDraw;
}
public void setNumberDraw(int numberDraw) {
this.numberDraw = numberDraw;
}
public int getNumberLoss() {
return numberLoss;
}
public void setNumberLoss(int numberLoss) {
this.numberLoss = numberLoss;
}
public int getMatchesPlayed() {
return matchesPlayed;
}
public void setMatchesPlayed(int matchesPlayed) {
this.matchesPlayed = matchesPlayed;
}
public int getPoints() {
return points;
}
public void setPoints(int points) {
this.points = points;
}
public int getGoalsScored() {
return goalsScored;
}
public void setGoalsScored(int goalsScored) {
this.goalsScored = goalsScored;
}
public int getGoalsConceded() {
return goalsConceded;
}
public void setGoalsConceded(int goalsConceded) {
this.goalsConceded = goalsConceded;
}
public int getTablePosition() {
return tablePosition;
}
public void setTablePosition(int tablePosition) {
this.tablePosition = tablePosition;
}
#Override
public String toString() {
return "TeamStatistic{" +
"teamName='" + teamName + '\'' +
", numberWin=" + numberWin +
", numberDraw=" + numberDraw +
", numberLoss=" + numberLoss +
", matchesPlayed=" + matchesPlayed +
", points=" + points +
", goalsScored=" + goalsScored +
", goalsConceded=" + goalsConceded +
", tablePosition=" + tablePosition +
'}';
}
}
public class FootballMatchStatisticsEngine {
public List<TeamStatistic> computeTeamStatistics(List<FootballMatch> footballMatches) {
List<TeamStatistic> teamStatistics = getTeamStatistics(footballMatches);
updatePosition(teamStatistics);
return teamStatistics;
}
private void updatePosition(List<TeamStatistic> teamStatistics) {
/*
This function apply the relative table position to each TeamStatistics.
*/
IntStream.range(0,teamStatistics.size()).forEach(i -> teamStatistics.get(i).setTablePosition(i+1));
}
private List<TeamStatistic> getTeamStatistics(List<FootballMatch> footballMatches) {
/*
The flat operation explode each match into two different TeamStatistics. One for home team and one for away team.
After I compute the groupBy operation over team name and reduce the resulting list of Team statistics sumurizing her data.
*/
return footballMatches
.stream()
.flatMap(fm -> footballMatchtoTeamStatistics(fm).stream())
.collect(groupingBy(TeamStatistic::getTeamName, reducing(getTeamStatisticReduceOperation())))
.values().stream().map(Optional::get)
.sorted(comparingInt(TeamStatistic::getPoints).reversed())
.collect(Collectors.toList());
}
private BinaryOperator<TeamStatistic> getTeamStatisticReduceOperation() {
return (x, y) ->
new TeamStatistic(
x.getTeamName(),
x.getNumberWin() + y.getNumberWin(),
x.getNumberDraw() + y.getNumberDraw(),
x.getNumberLoss() + y.getNumberLoss(),
x.getMatchesPlayed() + y.getMatchesPlayed(),
x.getPoints() + y.getPoints(),
x.getGoalsScored() + y.getGoalsScored(),
x.getGoalsConceded() + y.getGoalsConceded(), 0);
}
private List<TeamStatistic> footballMatchtoTeamStatistics(FootballMatch footballMatch) {
return Arrays.asList(
new TeamStatistic(
footballMatch.getHomeTeam(),
footballMatch.getFinalResult() == 'H' ? 1 : 0,
footballMatch.getFinalResult() == 'D' ? 1 : 0,
footballMatch.getFinalResult() == 'A' ? 1 : 0,
1,
footballMatch.getFinalResult() == 'H' ? 3 : footballMatch.getFinalResult() == 'D' ? 1 : 0,
footballMatch.getHomeTeamScore(),
footballMatch.getAwayTeamScore(),
0),
new TeamStatistic(
footballMatch.getAwayTeam(),
footballMatch.getFinalResult() == 'A' ? 1 : 0,
footballMatch.getFinalResult() == 'D' ? 1 : 0,
footballMatch.getFinalResult() == 'H' ? 1 : 0,
1,
footballMatch.getFinalResult() == 'A' ? 3 : footballMatch.getFinalResult() == 'D' ? 1 : 0,
footballMatch.getAwayTeamScore(),
footballMatch.getHomeTeamScore(),
0)
);
}
}
To test this code I write a file with the follow lines:
Arsenal,Leicester,4,3,H
Man City,Leicester,2,1,H
Brighton,Man City,0,2,A
Chelsea,Arsenal,0,2,A
Chelsea,Burnley,2,3,A
Crystal Palace,Huddersfield,0,3,A
Everton,Stoke,1,0,H
Southampton,Swansea,0,0,D
running the follow code
FootballMatchCSVReader reader = new FootballMatchCSVReader();
FootballMatchStatisticsEngine statisticsEngine = new FootballMatchStatisticsEngine();
try {
List<FootballMatch> footbalMatches = reader.read("src/test/resources/input.txt");
List<TeamStatistic> teamStatistics = statisticsEngine.computeTeamStatistics(footbalMatches);
teamStatistics.forEach(t -> System.out.println(t));
} catch (IOException e) {
e.printStackTrace();
}
This is the output
TeamStatistic{teamName='Arsenal', numberWin=2, numberDraw=0, numberLoss=0, matchesPlayed=2, points=6, goalsScored=6, goalsConceded=3, tablePosition=1}
TeamStatistic{teamName='Man City', numberWin=2, numberDraw=0, numberLoss=0, matchesPlayed=2, points=6, goalsScored=4, goalsConceded=1, tablePosition=2}
TeamStatistic{teamName='Huddersfield', numberWin=1, numberDraw=0, numberLoss=0, matchesPlayed=1, points=3, goalsScored=3, goalsConceded=0, tablePosition=3}
TeamStatistic{teamName='Everton', numberWin=1, numberDraw=0, numberLoss=0, matchesPlayed=1, points=3, goalsScored=1, goalsConceded=0, tablePosition=4}
TeamStatistic{teamName='Burnley', numberWin=1, numberDraw=0, numberLoss=0, matchesPlayed=1, points=3, goalsScored=3, goalsConceded=2, tablePosition=5}
TeamStatistic{teamName='Southampton', numberWin=0, numberDraw=1, numberLoss=0, matchesPlayed=1, points=1, goalsScored=0, goalsConceded=0, tablePosition=6}
TeamStatistic{teamName='Swansea', numberWin=0, numberDraw=1, numberLoss=0, matchesPlayed=1, points=1, goalsScored=0, goalsConceded=0, tablePosition=7}
TeamStatistic{teamName='Stoke', numberWin=0, numberDraw=0, numberLoss=1, matchesPlayed=1, points=0, goalsScored=0, goalsConceded=1, tablePosition=8}
TeamStatistic{teamName='Crystal Palace', numberWin=0, numberDraw=0, numberLoss=1, matchesPlayed=1, points=0, goalsScored=0, goalsConceded=3, tablePosition=9}
TeamStatistic{teamName='Brighton', numberWin=0, numberDraw=0, numberLoss=1, matchesPlayed=1, points=0, goalsScored=0, goalsConceded=2, tablePosition=10}
TeamStatistic{teamName='Chelsea', numberWin=0, numberDraw=0, numberLoss=2, matchesPlayed=2, points=0, goalsScored=2, goalsConceded=5, tablePosition=11}
TeamStatistic{teamName='Leicester', numberWin=0, numberDraw=0, numberLoss=2, matchesPlayed=2, points=0, goalsScored=4, goalsConceded=6, tablePosition=12}

How can I implement the count 60 seonds for hospital

Who can help me to implement the function if the patient waiting for over 60 seconds the category will change from "low" to "high" and queue behind the newest patient category with "high". Can someone help to me to solve it?
EmergencyRoomSimulator1.java :
package emergencyroomsimulator1;
import java.util.Random;
public class EmergencyRoomSimulator1 {
private static final int WAIT_LIMIT = 1000; // 1000 = 1 second
private PatientQueue pq = new PatientQueue();
private void t() {
try { Thread.sleep(new Random().nextInt(WAIT_LIMIT));
} catch (InterruptedException e) {
}
} // end t method
private void patientArrives(Patient p) {
pq.registerPatient(p);
System.out.println(" ARRIVAL: " + p.getID());
System.out.println(" time arrived: " + p.getTimeArrived());
System.out.println(" category: " + p.getCategory());
System.out.println("------------------------------------");
t();
} // end patientArrives method
public void doctorVisits() {
Patient p = pq.getNextPatient();
System.out.println(" VISIT: " + p.getID());
System.out.println(" time arrived: " + p.getTimeArrived());
System.out.println(" category: " + p.getCategory());
System.out.println("------------------------------------");
t();
} // end doctorVisits method
private void simulate() {
System.out.println("------------------------------------");
System.out.println("ER OPEN");
System.out.println("------------------------------------");
patientArrives(new Patient(100, "high"));
patientArrives(new Patient(101, "low"));
patientArrives(new Patient(102, "low"));
patientArrives(new Patient(103, "high"));
patientArrives(new Patient(104, "high"));
patientArrives(new Patient(105, "low"));
patientArrives(new Patient(106, "low"));
patientArrives(new Patient(107, "high"));
doctorVisits();
doctorVisits();
doctorVisits();
doctorVisits();
doctorVisits();
doctorVisits();
System.out.println("------------------------------------");
System.out.println("ER CLOSED");
System.out.println("------------------------------------");
}
public static void main(String[] args) {
// TODO code application logic here
EmergencyRoomSimulator1 er = new EmergencyRoomSimulator1();
er.simulate();
} // end main
}
Patient.java :
package emergencyroomsimulator1;
import java.util.Date;
public class Patient implements Comparable<Patient> {
protected int id;
protected String category;
protected Date timeArrived;
EmergencyRoomSimulator1 emg;
//protected Date CurrentTime;
// accessors and mutators
public int getID() {
return id;
}
public void setID(int idIn) {
this.id = idIn;
}
public String getCategory() {
return category;
}
public void setCategory(String categoryIn) {
this.category = categoryIn;
}
public java.util.Date getTimeArrived() {
return timeArrived;
}
public int compareTo(Patient other) {
// This code doesn't handle nulls
int result = getCategory().compareTo(other.getCategory());
if (result == 0) {
result = getTimeArrived().compareTo(other.getTimeArrived());
}
return result;
}
// default constructor
public Patient() {
this.id = 0;
this.category = "low"; // unclassified Patients go to the end of the queue
this.timeArrived = new Date();
}
// overloaded constructor
public Patient(int idIn, String categoryIn) {
this.id = idIn;
this.category = categoryIn;
this.timeArrived = new Date();
}
}
PatientComparator.java:
package emergencyroomsimulator1;
import java.util.Comparator;
public class PatientComparator implements Comparator<Patient>{
public int compare(Patient p1, Patient p2) {
int result = p1.getCategory().compareTo(p2.getCategory());
if (result == 0) {
result = p1.getTimeArrived().compareTo(p2.getTimeArrived());
}
return result;
}
}
PatientQueue.java :
package emergencyroomsimulator1;
import java.util.Comparator;
import java.util.PriorityQueue;
public class PatientQueue {
PriorityQueue pq;
// default constructor
public PatientQueue() {
this.pq = new PriorityQueue<Patient>(1, new PatientComparator());
}
public void registerPatient(Patient p) {
this.pq.add(p);
} // end registerPatient method
public Patient getNextPatient() {
return (Patient) this.pq.poll();
} // end getNextPatient method
}

Handling Condtion in ThreadPoolExecutor to execute

I have the following Scenario.
There is a restroom in a Building.
It will have 2 types[As of now] of toilet. MALE and FEMALE which is n in number.
If a group of People enters into a restroom.I want them to occupy maximum no of rooms as possible.
Assume there are 20 people entering into restroom at a time with the following combination
People 20
Male 10 Female 10
RestRoom Avaialbiltiy
MALE 2
FEMALE 1
And some people will take more time, so the next person have to wait in the queue.And male cannot enter into female toilet and vice-versa.
For the above scenario I have extended the ThreadpoolExecutor and add the Person one by one and check assign them as soon as toilet with match is avaialable.
So here is the MCVE for the example.I wanted to check if this is the correct way to handle condition in a ThreadPool
RestRoom.java
import java.util.HashMap;
import java.util.Map;
public enum RestRoom {
MALE,
FEMALE;//will extend for ex [Differently Abled]
public int maxInstance = 0;
public RestRoom withMaxInstance(int maxInstance) {
this.maxInstance = maxInstance;
return this;
}
public static int getTotalNoOfRestRooms() {
int count = 0;
for (RestRoom room : RestRoom.values()) {
count += room.maxInstance;
}
return count;
}
public static Map<RestRoom, Integer> getAvailabiltyAsMap() {
Map<RestRoom, Integer> avaialbilty = new HashMap<>();
for (RestRoom room : RestRoom.values()) {
avaialbilty.put(room, room.maxInstance);
}
return avaialbilty;
}
}
Person.java (Runnable)
import java.util.logging.Level;
import java.util.logging.Logger;
public class Person implements Runnable {
private final String name;
private final RestRoom gender;
private int second;
public Person(String name, RestRoom gender) {
this.name = name;
this.gender = gender;
}
public Person withTime(int second) {
this.second = second;
return this;
}
#Override
public void run() {
try {
System.out.println("Running " + name + " with " + gender);
Thread.sleep(second * 1000);
} catch (InterruptedException ex) {
Logger.getLogger(Person.class.getName()).log(Level.SEVERE, null, ex);
}
}
public String getName() {
return name;
}
public RestRoom getGender() {
return gender;
}
#Override
public String toString() {
return "Person{" + "name=" + name + ", gender=" + gender + '}';
}
}
CustomThreadPool.java
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class CustomThreadPool extends ThreadPoolExecutor {
Map<RestRoom, Integer> avaialbilty = new HashMap<>();
LinkedBlockingDeque<Runnable> remaining = new LinkedBlockingDeque<>();
public CustomThreadPool(int corePoolSize, long keepAliveTime) {
super(corePoolSize, corePoolSize, keepAliveTime, TimeUnit.MINUTES, new LinkedBlockingDeque<Runnable>());
avaialbilty = RestRoom.getAvailabiltyAsMap();
}
#Override
protected void afterExecute(Runnable runnable, Throwable throwable) {
avaialbilty.put(getRestRoomFor(runnable), avaialbilty.get(getRestRoomFor(runnable)) + 1);
for (int i = 0; i < remaining.size(); i++) {
execute(remaining.remove());
}
if (remaining.isEmpty()) {
shutdown();
}
}
#Override
public void execute(Runnable runnable) {
if (avaialbilty.get(getRestRoomFor(runnable)) > 0) {
avaialbilty.put(getRestRoomFor(runnable), avaialbilty.get(getRestRoomFor(runnable)) - 1);
super.execute(runnable);
} else {
remaining.add(runnable);
}
}
private RestRoom getRestRoomFor(Runnable runnable) {
return asPerson(runnable).getGender();
}
private Person asPerson(Runnable runnable) {
return (Person) runnable;
}
}
Test.java
public class Test {
public static void main(String[] args) {
RestRoom.MALE.withMaxInstance(3);
RestRoom.FEMALE.withMaxInstance(2);
CustomThreadPool threadPool = new CustomThreadPool(RestRoom.getTotalNoOfRestRooms(), 2);
for (int i = 0; i < 10; i++) {
threadPool.execute(new Person("M" + i, RestRoom.MALE).withTime(2));
threadPool.execute(new Person("F" + i, RestRoom.FEMALE).withTime(1));
}
}
}

how to populate jcombobox with arrays that match specific criteria

When i try my code below the list isn't be populated with the specific arrays please help i'm pretty new to coding GUI in netbeans
private void bookingListJCBActionPerformed(java.awt.event.ActionEvent evt) {
for(int i = 0;i<dataSource.getBookingList().size();i++){
Bookings tempBooking = dataSource.getBookingList().get(i);
boolean tempFinish = tempBooking.getFinish();
String tempMechanic = tempBooking.getMechanic();
String tempClerk = tempBooking.getClerk();
String tempService = tempBooking.getService();
if(tempFinish == true){
bookingListJCB.addItem(tempBooking);
mechanicJTF.setText(tempMechanic);
seriveceClerkJTF.setText(tempMechanic);
serviceJTF.setText(""+tempService );
finishJTF.setText(""+tempFinish);
}
}
// TODO add your handling code here:
}
Here is the Bookings class how i don't know why the combo box isn't displaying anything
public class Bookings {
private String vehicle;
private String clerk;
private String service;
private String mechanic;
private boolean finish;
public Bookings() {
}
public Bookings(String vehicle, String clerk, String service, String mechanic, boolean finish) {
this.vehicle = vehicle;
this.clerk = clerk;
this.service = service;
this.mechanic = mechanic;
this.finish = finish;
}
public String getVehicle() {
return vehicle;
}
public void setVehicle(String vehicle) {
this.vehicle = vehicle;
}
public String getClerk() {
return clerk;
}
public void setClerk(String clerk) {
this.clerk = clerk;
}
public String getService() {
return service;
}
public void setService(String service) {
this.service = service;
}
public String getMechanic() {
return mechanic;
}
public void setMechanic(String mechanic) {
this.mechanic = mechanic;
}
public boolean getFinish() {
return finish;
}
public void setFinish(boolean finish) {
this.finish = finish;
}
#Override
public String toString() {
return "Bookings{" + "vehicle=" + vehicle + ", clerk=" + clerk + ", service=" + service + ", mechanic=" + mechanic + ", finish=" + finish + '}';
}
}

Categories