I am having a sorted ArrayList like-
List<DD_Details> list = new ArrayList<DD_Details>();
list.add(new DD_Details(26/05/2014,3000.00));
list.add(new DD_Details(26/08/2014,6000.00));
list.add(new DD_Details(26/08/2014,2000.00));
DD_Details Class is -
class DD_Details {
private Date ddSubmissionDate;
private Double amount;
public DD_Details(Date n, Double s) {
this.ddSubmissionDate = n;
this.amount = s;
}
public Date getDdSubmissionDate() {
return ddSubmissionDate;
}
public void setDdSubmissionDate(Date ddSubmissionDate) {
this.ddSubmissionDate = ddSubmissionDate;
}
public Double getAmount() {
return amount;
}
public void setAmount(Double amount) {
this.amount = amount;
}
public String toString() {
return "ddSubmissionDate: " + this.ddSubmissionDate + "-- amount: "
+ this.amount;
}
}
i just want to add amount values of the same date and store in a new ArrayList.
I tried below code but it is not working properly.
for (int i = 0; i < list.size(); i++) {
Double amt = 0.0;
Date date1 = list.get(i).getDdSubmissionDate();
for (int j = i + 1; j < list.size(); j++) {
if (date1.equals(list.get(j).getDdSubmissionDate())) {
amt = amt + list.get(j).getAmount() + list.get(i).getAmount();
} else {
amt = list.get(i).getAmount();
}
}
list1.add(new DD_Details(date1, amt));
}
Please give me some hint to get it done. Thanks in Advance.
You can use next solution instead:
List<DD_Details> list = new ArrayList<DD_Details>();
List<DD_Details> list1 = new ArrayList<DD_Details>();
list.add(new DD_Details(new Date(2014, 5, 26), 3000.00));
list.add(new DD_Details(new Date(2014, 8, 26), 6000.00));
list.add(new DD_Details(new Date(2014, 8, 26), 2000.00));
for (DD_Details currentEl : list) // iterate over 'list'
{
DD_Details existingElement = null;
for (DD_Details el1 : list1) // find element in 'list1' with the same date
{
if (el1.getDdSubmissionDate().equals(currentEl.getDdSubmissionDate()))
{
existingElement = el1;
break;
}
}
if (existingElement == null) // if element is not found in 'list1' then add current element to list
{
list1.add(currentEl); // or list1.add(new DD_Details(el.getDdSubmissionDate(), el.getAmount()))
}
else // if element is found, then increase amount
{
existingElement.setAmount(existingElement.getAmount() + currentEl.getAmount());
}
}
// 'list1' contains what you need
In the inner for, when you are adding the values for a particular date, there is an error in the else part. You try to iterate through the list for a given date and add all the values until the date is different. Once you reach this condition, you get inside the else and set the sum to be the amount of the first element of this given date, therefore you are overriding the sum you had calculated. Moreover, for every new element with the same date, you are adding the amount of the first date, which means that if there are 4 elements of the same date, you will be adding 3 times the first amount.
What you should do, is get the amount for that given date before entering the second loop. One final consideration, is that you are going to get different amounts for different dates because imagine you have 3 elements with the same date, with the loop you are using, you will start with the first one, get the amount of the 3 elements added, then go to the second and get the amount of the second and third added, and finally move to the last one and create a third element with the amount of only the third element. Therefore, you should create a third variable which I called k, and store the last j value that contained the same date, to then add it to i and avoid iterating through an element with a date you already processed:
for (int i = 0; i < list.size(); i++) {
Double amt = list.get(i).getAmount();
Date date1 = list.get(i).getDdSubmissionDate();
int k = 0;
for (int j = i + 1; j < list.size(); j++) {
if (date1.equals(list.get(j).getDdSubmissionDate())) {
amt = amt + list.get(j).getAmount();
k = j;
}
}
list1.add(new DD_Details(date1, amt));
i += k++;
}
Your dates should be String literals. The way you've written them they will be ints and all equal to 0.
The obvious solution would be to build a Map of dates to amounts (instead of a list) and after adding all the entries iterating the map to build your list. Something like:
Map<Date, Double> amountPerDate = new HashMap<>();
List<Date> dates = ...;
List<Double> amounts = ...; // wherever those may come from
for(int i = 0; i < dates.size(); i++) {
Double currentAmount = amountPerDate.get(dates.get(i));
double amount = currentAmount == null ? 0 : currentAmount;
amountPerDate.put(dates.get(i), amount + amounts.get(i));
}
List<DD_Details> details = new ArrayList<>();
for(Entry<Date, Double> e : amountPerDate) {
details.put(new DD_Details(e.getKey(), e.getValue());
}
// optionally, you may Collections.sort(details); the list
In your DD_Details class, consider using a primitive double instead of a boxed Double.
I guess that your problem is in your second for-loop in the else-part of the if-statement. Even if you have dates which match you will have some dates which will not match. Thus you set back your amount the the amount of i.
You should add:
System.out.println("The dates are equal. New amount is: " + amt);
to your if-statement and:
System.out.println("Dates do not match. " + amt);
Now you should see that you add the amount the correct way but you reset it in the else part several times.
Related
I'm trying to make a simple billing system for a restaurant.
This shows the menu to the user and lets them choose, add an Item or quit.
In the end, it prints the bill.
The issue I'm facing is, I want the user to be able to add an item again with the item's number instead of overwriting the value.
Below code is my attempt which doesn't return anything.
public void addOrder(String meal, int quantity,
String[] dish, double[] cost) {
for (int i = 0; i < orderedFood.size(); i++) {
// look if food item already exists, update quantity of it by
// adding the previous value of the item to the new amount
if (orderedFood.get(i).contains(meal)) {
int oldQuantity = orderedQuantity.get(i);
orderedQuantity.set(i, oldQuantity + quantity);
break;
} else {
// if theres no item of this type yet, create a new one
orderedFood.add(meal);
orderedQuantity.add(quantity);
}
}
The code below shows how the food object gets created, and how the program works.
public static void Order() {
String[] dish = {"Sandwich", "Coffee", "Salad"};
double[] cost = {6.5, 3.2, 4.0};
for (int i = 0; i < dish.length; i++) {
System.out.println("\n" + dish[i] + ": " + cost[i] + "€.");
}
System.out.println("\nWhat would you like to order? \n\n");
Scanner myObj = new Scanner(System.in);
List<String> dishList = new ArrayList<>(Arrays.asList(dish));
// check if item exists
String menuItemTemp = myObj.nextLine();
String menuItem = "";
if (dishList.contains(menuItemTemp)) {
System.out.println("\nOkay.\n");
menuItem = menuItemTemp;
} else {
System.out.println("Error 404 Not Found.");
Order();
}
System.out.println("\nHow many? \n");
int userQuant = myObj.nextInt();
Bill myBill = new Bill();
myBill.addOrder(menuItem, userQuant, dish, cost);
System.out.println("\nOrder more? 1 - Yes. 2 - No. \n");
Scanner menuScan = new Scanner(System.in);
int menuScanner = menuScan.nextInt();
switch (menuScanner) {
// if another order is to be made
case 1:
System.out.println("\nOkay.");
Order();
break;
// output and end of program
case 2:
myBill.getOrder();
System.out.println(Math.round(myBill.getTotal() * 100.00) / 100.00 + "€\n");
System.out.println("\nThanks for ordering!\n");
// close scanners
menuScan.close();
myObj.close();
// end
System.exit(1);
}
Any nudge in the right direction would help a lot.
The error is the premature else. When not already present, you need to walk the entire for loop before knowing that there is no match.
If you do return instead of break you can treat the not-found case after the for.
public void addOrder(String meal, int quantity,
String[] dish, double[] cost) {
for (int i = 0; i < orderedFood.size(); i++) {
// look if food item already exists, update quantity of it by
// adding the previous value of the item to the new amount
if (orderedFood.get(i).contains(meal)) {
int oldQuantity = orderedQuantity.get(i);
orderedQuantity.set(i, oldQuantity + quantity);
return;
}
}
// if theres no item of this type yet, create a new one
orderedFood.add(meal);
orderedQuantity.add(quantity);
}
Of course
for
orderedFood.get(i).contains(meal)
int oldQuantity = orderedQuantity.get(i);
orderedQuantity.set(i, oldQuantity + quantity);
hints that an other data structure might be better:
Map<String, Integer> ordered = new HashMap<>(); // Meal to quantity.
public void addOrder(String meal, int quantity,
String[] dish, double[] cost) {
ordered.merge(meal, quantity, Integer::sum);
}
That is map the meal names to the total quantity. Indices are irrelevant.
Map.merge works as follows:
merge(K key, V value, (Value oldv, Value newv) -> resultv)
If newv is null, a remove is done.
Otherwise:
The lambda is called with an (possibly accumulating) old value, and the passed value.
if (oldv == null)
put(key, newv);
else
put(key, oldv + newv); // newv == value
Integer::sum is the same as (x, y) -> x + y.
So I would've left a comment if could've however I don't have enough reputation for that yet. I'm not sure what your myBill.getTotalOrder() function is. My first thought here without seeing more of your source code to understand your design would be to just make a Meal object that tracks its name, how much it is, and how many times it was ordered. Then during your getTotalOrder() you could just loop through each meal and add up the total.
I have to backtracking with numbers in a list that represent restrictions, such as: "x1 + x2> = 1". And if it meets all the conditions, that array is added to another array, in addition there is another list that represents the sum that I must make with all the variables "x1 + x2 + x3 + x4" and with that search for the one with the minimum value.
good what I should do in backtraking is to make a binary matrix with all the possibilities that the restrictions meet. What I have done is this but I get the error: "Exception in thread" main "java.lang.IndexOutOfBoundsException: Index 2 out of bounds for length 0" and I don't know where my problem is.
import java.util.ArrayList;
public class Pra_hacer_pruebas {
public static void main(String[] args) {
Pra_hacer_pruebas a = new Pra_hacer_pruebas();
ArrayList<Integer> conf1= new ArrayList<>(); // conf1 is the list that will contain one of the possibilities that may or may not be added to the binary matrix.
ArrayList<ArrayList<Integer>>pos_v = new ArrayList<>();// pos_v is where the possibilities will be added, binary matrix
int[][] restric = new int[2][2];// restric is the list with restrictions
restric[0][0]=2;
restric[0][1]=1;
restric[1][0]=4;
restric[1][1]=2;
for(int t=0;t<4;t++){
conf1.set(t, -1);
}
//System.out.println(conf.get(i));
a.binario(conf1,restric,0,0,0,pos_v,0,4,-1);
}
public void binario(ArrayList<Integer> conf1, int[][] restric, int suma,int filas,int columnas,ArrayList<ArrayList<Integer>> pos_validas,int posicion, int cont,int bin){
//filas = rows, suma= sum is to see if it meets the condition, columnas = columns, pos_validas = pos_v, posicion is to advance the rows of the matrix, cont: is the amount of different variables, bin is the binary variable
Boolean booleano = false; // booleano is the flag that if it is true it is because there was a null position (-1)
for (int[] restric1 : restric) {
suma=0;
for (int co = 0; co < restric1.length; co++) {
if ((conf1.get(restric1[co]) == 1) || (conf1.get(restric1[co]) == 0)) {
suma = suma + conf1.get(restric1[co]);
} else {
booleano = true;
}
}
if (booleano == false) {
if (suma < 1){
break;
}
}
}
if (booleano == false) {
pos_validas.set(posicion, conf1);
posicion++;
}
for (int f = 0; f < cont; f++) {
if (conf1.get(f) < 1) {
bin++;
conf1.set(f, bin);
binario(conf1,restric,suma,filas,columnas,pos_validas,posicion,cont,bin);
}
bin--;
}
}
}
Try add method. Even if you create ArrayList with initialCapacity, It won't works as you intended. If you print ArrayList size before set, You can check it.
System.out.println(conf1.size());
for(int t=0; t<4; t++){
conf1.set(t, Integer.valueOf(-1));
}
Modify code to use add
for(int t=0; t<4; t++){
conf1.add(-1);
}
your Arraylist objects start out as empty objects. YOu can't call .set() on them at all: Those UPDATE existing entries, they don't make new ones. Try add.
I want to generate some test data using this Java code:
#GetMapping("/volumes")
public ResponseEntity<List<DashboardDTO>> getProcessingVolumes() {
return ResponseEntity.ok(testDate());
}
public List<DashboardDTO> testDate() {
List<DashboardDTO> list = null;
for (int i = 0; i <= 10; i++) {
list = new ArrayList<>();
DashboardDTO obj = new DashboardDTO();
obj.setAmount(ThreadLocalRandom.current().nextInt(20, 500 + 1));
LocalDate localDate = LocalDate.now().minus(Period.ofDays((new Random().nextInt(365 * 70))));
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
obj.setDate(date);
obj.setNumber_of_transactions(ThreadLocalRandom.current().nextInt(300, 5000 + 1));
list.add(obj);
}
return list;
}
But when the code is run only one object is generated. Do you know where I'm wrong? I want to generate 10 test objects.
Here:
for (int i = 0; i <= 10; i++) {
list = new ArrayList<>();
You create a new result list during each loop. So the last loop creates another list for the last entry!
Simply move that line list = new ArrayList<>(); in front of the loop, so that it gets executed just once.
Your code creates 11 new lists, each one with one entry, and you return that last list object. Instead: create one list and add your 11 elements and then return that single list.
for (int i = 0; i <= 10; i++) {
list = new ArrayList<>(); //(Fix here)--> resetting your list everytime causing only single object to return.
Try to initialize only single time.
List<DashboardDTO> list = new ArrayList<>();
for (int i = 0; i <= 10; i++) {
DashboardDTO obj = new DashboardDTO();
obj.setAmount(ThreadLocalRandom.current().nextInt(20, 500 + 1));
LocalDate localDate = LocalDate.now().minus(Period.ofDays((new Random().nextInt(365 * 70))));
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
obj.setDate(date);
obj.setNumber_of_transactions(ThreadLocalRandom.current().nextInt(300, 5000 + 1));
list.add(obj);
}
return list;
I want to sort my LineChart X axis in JavaFX. I have Dates(X axis) from DatePicker and their Values(Y axis), but there are for exaple four exactly the same dates and different values. What I want to do is that I need to check if date exist, and if yes, I want to add the value to that date. Sorry about my english.
Look at my Linechart.
The first date has three values. I want to add them.
here is my code:
void initLineChart()
{
//defining a series
XYChart.Series<String,Number> series = new XYChart.Series<String, Number>();
lineChart.setAxisSortingPolicy(LineChart.SortingPolicy.X_AXIS);
String date = new String();
int numb;
String value = new String();;
ShowDreamHistoryController.save();
ShowDreamHistoryController.loadDreamAtStart();
for (int i = 0; i < ShowDreamHistoryController.listDreams.size(); i++) {
date = ShowDreamHistoryController.listDreams.get(i).getDate().toString();
value = ShowDreamHistoryController.listDreams.get(i).getHours();
if(value != null)
{
numb = Integer.valueOf(value);
series.getData().add(new XYChart.Data<String,Number>(date, numb));
}
}//for
// System.out.println(datesOnes);
lineChart.getData().add(series);
}
Check if the date exists in series and if it does, remove that index and add to it.
int indexExist = existAt(series,date);
if(indexExist < 0){ // if the date does not exist
series.getData().add(new XYChart.Data<String, Number>(date, numb));
} else { //if the date exists
int curVal = series.getData().get(indexExist).getYValue().intValue();
//get the current value stored in that date
series.getData().remove(indexExist);
// remove the index
series.getData().add(indexExist, new XYChart.Data<String,Number>(date, curVal + value));
// add to that index ( current value + value )
}
Then we would have a function that looks for the index.
/*
Loop through "SERIES" and return the position of the string
-1 if it doesn't exist.
*/
public int existAt(XYChart.Series <String, Number> series, String date){
for(int i=0; i<series.getData().size(); i++){
if(series.getData().get(i).getXValue().equals(date)){
return i;
}
}
return -1;
}
I am working on an algorithm, and I need to be able to pass in a List and see if there are four numbers in a row at any point in the list.
I have been struggling with an easy way to do this... Here is the basic idea.. I would like the fourNumbersInARow() method to return true:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Numbers {
/**
* #param args
*/
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<Integer>();
for(int i = 0; i<10; i++){
numbers.add((new Random().nextInt()));
}
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
System.out.println(fourNumbersInARow());
}
private static boolean fourNumbersInARow() {
}
}
Use two variables: last_value and row_count. Going through the list one by one, always look whether the current value is exactly one bigger than the last_value; if yes, increase row_count, if no, reset it to 1. In any case, set last_value to the current value and loop. If at any point row_count becomes 4, return true. If you reach the end of the list, return false.
EDIT: changed counter range to start at 1
Here's an implementation in Java.
static boolean fourNumbersInARow(List<Integer> list) {
int last = 0xFACADE; // can be any number
int count = 0; // important!
for (int i : list) {
if (i == last + 1) {
if (++count == 4) return true;
} else {
count = 1;
}
last = i;
}
return false;
}
Unlike others, this resets the count of numbers in a row to 1 when the sequence is broken (because a number on its own is 1 number in a row). This allows for easier treatment of the first iteration where technically there is no previous number.
In pseudocode:
consecutiveCount = 1
lastNumber = firstElementInList(list)
for (number in list.fromSecondElement()):
if (number - lastNumber == 1):
consecutiveCount++
else:
consecutiveCount = 1
if (consecutiveCount == 4):
return true
lastNumber = number
return false
The bottom line is, you'll want to keep track of the last number in that was in the list, and compare it with the current number to see if the difference is 1. In order to remember the last number, a variable such as lastNumber is needed.
Then, in order to keep track of how many consecutive numbers there have been there should be a counter for that as well, which in the example about is the consecutiveCount.
When the condition where four consecutive numbers have occurred, then the method should return true.
This sounds a little like a homework question, so I don't want to write out a complete solution. But in your method just iterate through the list. Take the first number and see if the next number comes after the current, if so then set a variable flag with the start position and the current number, on the next iteration through the loop check to see if that value is before the previous the value etc... Once four in a row are found, break out of the loop and return true. If you encounter a number that is no chronologically correct then set a flag(start location) to null or negative and start the process over from the current location in the list.
Check this Code, this will return true if there a sequence of 4 numbers and else false otherwise
public class FindFourSequence {
public boolean isFourinRow(ArrayList seqList) {
boolean flag = false;
int tempValue = 0;
int tempValue2 = 0;
int tempValue3 = 0;
int tempValue4 = 0;
Iterator iter = seqList.iterator();
while(iter.hasNext()){
String s1 = (String)iter.next();
tempValue=Integer.valueOf(s1).intValue();
if(!(iter.hasNext())){
break;
}
String s2 = (String)iter.next();
tempValue2=Integer.valueOf(s2).intValue();
if(((tempValue2-tempValue)==1) || (tempValue-tempValue2)==1){
if(!(iter.hasNext())){
break;
}
String s3 = (String)iter.next();
tempValue3=Integer.valueOf(s3).intValue();
if((tempValue3-tempValue2)==1 || (tempValue2-tempValue3)==1){
if(!(iter.hasNext())){
break;
}
String s4 = (String)iter.next();
tempValue4=Integer.valueOf(s4).intValue();
if((tempValue3-tempValue4==1) || (tempValue4-tempValue3)==1){
flag = true;
return flag;
}
}
}
}
return flag;
}
public static void main(String[] args) throws Exception {
ArrayList aList = new ArrayList();
boolean flag = false;
FindFourSequence example = new FindFourSequence();
Random random = new Random();
for (int k = 0; k < 25; k++) {
int number = random.nextInt(20);
System.out.println(" the Number is :" + number);
aList.add("" + number);
}
/* aList.add("" + 1);
aList.add("" + 2);
aList.add("" + 3);
aList.add("" + 4);*/
flag = example.isFourinRow(aList);
System.out.println(" the result value is : " + flag);
}
}