I am new at android and trying to make managing members app with database. what i want to do here is that when user buys any drink it should change drinks name to "bought" in database, but when i pass Arraylist to db class it shows that my Arraylist is empty.
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:437)
at com.shashank.managemembers.DB_Controller.update_available(DB_Controller.java:88)
at com.shashank.managemembers.TempActivity$2.onClick(TempActivity.java:90)
userInputActivity
here user selects drink he/she wants and when he presses done button it should change database with drinks name.
And I'm checking it with Toast message that ArrayList is not empty. Toast message always appears with user's choice but db class throws error.
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(TempActivity.this, selectedInListView.get(0), Toast.LENGTH_SHORT).show();
dbController.update_available(code, selectedInListView);
onBackPressed();
}
});
here selectedInListView has many items when i am passing it to dbController.update_available.
dbController.java
here I have 9 columns in db starting from DRINK1 to DRINK9.
public void update_available(String memberCode, ArrayList<String> BoughtDrinks) {
Cursor cursor = this.getReadableDatabase().rawQuery("SELECT * FROM MEMBERS WHERE MEMBERCODE = '" + memberCode + "'", null);
int count = cursor.getColumnCount();
while (cursor.moveToNext()) {
for (int i = 5; i < count; i++) {
if (!cursor.getString(i).contains(BoughtDrinks.get(0))) {
this.getReadableDatabase().execSQL("UPDATE MEMBERS SET DRINK"+ i +"='Bought' WHERE DRINK" + i +"='" + BoughtDrinks.get(0) + "'" + "AND MEMBERCODE='" + memberCode + "'");
if(BoughtDrinks.size() > 0 ){
BoughtDrinks.remove(0);
}
}
}
}
cursor.close();
}
I am not understanding why it is throwing an error when I'm passing ArrayList with elements.
You got this error because ,if BoughtDrinks.size()>0 ,your code remove item at 0 then for loop get item at 0.So when you try to get item at 0 after you removed all the item ,you will get index IndexOutOfBoundsException.to avoid that just add if() condition.
public void update_available(String memberCode, ArrayList<String> BoughtDrinks) {
Cursor cursor = this.getReadableDatabase().rawQuery("SELECT * FROM MEMBERS WHERE MEMBERCODE = '" + memberCode + "'", null);
int count = cursor.getColumnCount();
while (cursor.moveToNext()) {
for (int i = 5; i < count; i++) {
if ( BoughtDrinks.size()>0 && !cursor.getString(i).contains(BoughtDrinks.get(0))) {
this.getReadableDatabase().execSQL("UPDATE MEMBERS SET DRINK"+ i +"='Bought' WHERE DRINK" + i +"='" + BoughtDrinks.get(0) + "'" + "AND MEMBERCODE='" + memberCode + "'");
if(BoughtDrinks.size() > 0 ){
BoughtDrinks.remove(0);
}
}
}
}
cursor.close();
}
I've been tasked as an assignment to make a queue, that is supposed to be simulated 10 times, and for it to have a waiting room that can hold 100 customers.
I was able to simulate it 10 times, but the assignment mentions criteria such as having an average waiting time of x minutes, having a minimum number of served customers, and at the end have a maximum number of those waiting in line.
Here are my classes
Customer.class
public class Customer {
int arrivalTime;
int transactionTime;
int customerNumber;
public Customer(int a, int t, int c) {
arrivalTime = a;
transactionTime = t;
customerNumber = c;
}
public int getArrivalTime() {
return arrivalTime;
}
public int getTransactionTime() {
return transactionTime;
}
public int getCustomerNumber() {
return customerNumber;
}
}
WaitLine.class
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
public class WaitLine {
private static QueueInterface<Customer> line;
private static int numberOfArrivals;
private static int numberServed;
private static int totalTimeWaited;
public WaitLine() {
line = new LinkedQueue<Customer>();
reset();
}
public final void reset() {
line.clear();
numberOfArrivals = 0;
numberServed = 0;
totalTimeWaited = 0;
}
public void simulate(int duration, double arrivalProbability, int maxTransactionTime) {
int transactionTimeLeft = 0;
for (int clock = 0; clock < duration; clock++) {
if (Math.random() < arrivalProbability) {
numberOfArrivals++;
int transactionTime = (int) (Math.random() * maxTransactionTime + 1);
Customer nextArrival = new Customer(clock, transactionTime, numberOfArrivals);
line.enqueue(nextArrival);
System.out.println("Customer " + numberOfArrivals + " enters line at time " + clock
+ ". Transaction time is " + transactionTime);
}
if(transactionTimeLeft > 0) {
transactionTimeLeft--;
}else if(!line.isEmpty()) {
Customer nextCustomer = line.dequeue();
transactionTimeLeft = nextCustomer.getTransactionTime()-1;
int timeWaited = clock - nextCustomer.getArrivalTime();
totalTimeWaited += timeWaited;
numberServed++;
System.out.println("Customer " + nextCustomer.getCustomerNumber() + " begins service at time " + clock + ". Time waited is " + timeWaited );
}
}
}
public void displayResults() {
System.out.println();
System.out.println("Number served = " + numberServed);
System.out.println("Total time Waited = " + totalTimeWaited);
double averageTimeWaited = ((double)totalTimeWaited) / numberServed;
System.out.println("Average time waited = " + averageTimeWaited);
int leftInLine = numberOfArrivals - numberServed;
System.out.println("Number left in line " + leftInLine);
}
}```
I am currently stuck on meeting the criteria described, I put the simulate function in a loop that looped 10 times and after that I used displayresults, but my results did not fit the criteria.
Any help is appreciated, thank you.
transactionTime is handled in the main method/simulation(s) and not on the customer instance itself. Yo just need the arrivalTime and departureTime, and the constructor only needs to be Customer( int arrives ). Then you just need getArrivalTime() setDepartureTime(int time) and totalTime()
Then use import java.util.*; with Queue<Customer> line = new LinkedList<Customer>() and from there you just need the main method using that queue and the customer class that I modified above.
I have two tables, one is Info and another is WorkDetails.
Table Info: ID(PK), Name, Weather, Date, Status, TimeIn_Info, TimeOut_Info
Table WorkDetails: ID(PK),Project,WorkDescription,Per,TimeIn,TimeOut // 4 row
For the row in WorkDetails, only the row that has value will be inserted. Otherwise, it will not be inserted. Next, the TimeOut_Info in the table Info will used to get the value of TimeOut in the table WorkDetails. It will search from the fourth row, check whether there exists TimeOut value. If not, it will check the third and so on. If TimeOut value found in third row, it will insert the TimeOut value into Table info and will not check for second and first. Same goes to the TimeIn_info, the difference is TimeIn_info start searching from first row, not the fourth row.
Button btn1=(Button)findViewById(R.id.button2);
btn1.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
AlertDialog.Builder builder=new AlertDialog.Builder(WorkDetailsTable.this);
builder.setTitle("Data Saved");
builder.setMessage("Are you sure you want to save?");
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int ii) {
W1 = txtWork1.getText().toString();
W2 = txtWork2.getText().toString();
W3 = txtWork3.getText().toString();
W4 = txtWork4.getText().toString();
a1 = spinnerTra.getSelectedItem().toString();
a2 = spinnerTra2.getSelectedItem().toString();
a3 = spinnerTra3.getSelectedItem().toString();
a4 = spinnerTra4.getSelectedItem().toString();
P1 = per1.getText().toString();
P2 = per2.getText().toString();
P3 = per3.getText().toString();
P4 = per4.getText().toString();
// long ab = ts.insertTimeSheet(name, weather, date, status);
// long cf= WF.insertWorkForce(subContractors, noPeople, noHours,ab);
if ((TextUtils.isEmpty(W4)) && (TextUtils.isEmpty(P4)) && (TextUtils.isEmpty(h)) && (TextUtils.isEmpty(i))) {
checkRow3(W3, P3, f, g);// check row 3;
checkRow2(W2, P2, d, e1);//check row 2;
checkRow1(W1, P1, b, c);
}
else if (!(TextUtils.isEmpty(i)))
{
WD.insertWorkDetails(a4, W4, P4, h, i);
database = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(MyDatabaseHelper.TimeOut_Info, i);
database.insert(MyDatabaseHelper.TABLE_INFO, null, values);
checkRow3(W3, P3, f, g);// check row 3;
checkRow2(W2, P2, d, e1);//check row 2;
checkRow1(W1, P1, b, c);
}
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int ii) {
dialog.dismiss();
}
});
builder.show();
}
});
}
public void checkRow3(String a, String b, String c, String d) {
if ((TextUtils.isEmpty(a)) && (TextUtils.isEmpty(b)) && (TextUtils.isEmpty(c)) && (TextUtils.isEmpty(d))) {
}
else if ((!(TextUtils.isEmpty(a)))||(!(TextUtils.isEmpty(b)))||(!(TextUtils.isEmpty(c)))&&((TextUtils.isEmpty(d)))) {
WD.insertWorkDetails(a3, a, b, c, d);
}
else if ((!(TextUtils.isEmpty(a)))||(!(TextUtils.isEmpty(b)))||(!(TextUtils.isEmpty(c)))&&(!(TextUtils.isEmpty(d))))
{
WD.insertWorkDetails(a3, a, b, c, d);
database = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(MyDatabaseHelper.TimeIn_Info, d);
database.insert(MyDatabaseHelper.TABLE_INFO, null, values);
}
return;
}
public void checkRow2(String a, String b, String c, String d)
{
if ((TextUtils.isEmpty(a)) && (TextUtils.isEmpty(b)) && (TextUtils.isEmpty(c)) && (TextUtils.isEmpty(d)))
{
return ;
}
else
{
WD.insertWorkDetails(a2, a, b, c, d);
}
return;
}
public void checkRow1(String a, String b, String c, String d)
{
WD.insertWorkDetails(a1, a, b, c, d);
database = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(MyDatabaseHelper.TimeIn_Info, c);
database.insert(MyDatabaseHelper.TABLE_INFO, null, values);
return;
}
As you can see my code is a little bit confusing. Does it has any method that can search whether the column (TimeOut_info) already has a value?
How can I check whether the column is NULL or NOT NULL? If it is NULL, then TimeOut value will be inserted into TimeOut_Info, otherwise it will not! How can I achieve this?
When I attempt to use this method to check whether the specific column contains value or not, but I get rawQyery cannot be solved.
public void checkRow2(String a, String b, String c, String d)
{
if ((TextUtils.isEmpty(a)) && (TextUtils.isEmpty(b)) && (TextUtils.isEmpty(c)) && (TextUtils.isEmpty(d)))
{
}
else if ((!(TextUtils.isEmpty(a)))||(!(TextUtils.isEmpty(b)))||(!(TextUtils.isEmpty(c)))&&((TextUtils.isEmpty(d)))) {
WD.insertWorkDetails(a3, a, b, c, d);
}
else if ((!(TextUtils.isEmpty(a)))||(!(TextUtils.isEmpty(b)))||(!(TextUtils.isEmpty(c)))||(!(TextUtils.isEmpty(d))))
{
database = dbHelper.getWritableDatabase();
//Cursor mCursor=db.rawQuery("SELECT TimeOut_Info FROM "+MyDatabaseHelper.TABLE_INFO+"WHERE"+MyDatabaseHelper.TimeOut_Info+"=' "+d+"'");
Cursor mCursor = database.rawQuery("SELECT TimeOut_Info FROM " + MyDatabaseHelper.TABLE_INFO + " WHERE " +MyDatabaseHelper.TimeOut_Info + "= '" + d + "'");
if(c==null)
{
}
}
return;
}
Any suggestions? Thanks
There is no overloaded method of rawQuery which takes one parameter.
Change
Cursor mCursor = database.rawQuery("SELECT TimeOut_Info FROM " + MyDatabaseHelper.TABLE_INFO + " WHERE " +MyDatabaseHelper.TimeOut_Info + "= '" + d + "'");
with
Cursor mCursor = database.rawQuery("SELECT TimeOut_Info FROM " + MyDatabaseHelper.TABLE_INFO + " WHERE " +
MyDatabaseHelper.TimeOut_Info + "= '" + d + "'" , null);
you are already providing the selectionArgs, hardcoded in your query. Passing null should be ok in your case. Have a look here
I have a string (breakmsg) that I would like to be the same for every if statement, with an integer value that needs to change depending on what it is declared as inside the if statement. How would I go about changing the value of the value variable after I have already declared the breakmsg string? Previous attempts are commented inside the code.
Here is my current code:
private int value;
public void setValue(int v){
value = v;
}
#EventHandler
public void onBlockBreak(BlockBreakEvent e) {
Block b = e.getBlock();
Player p = e.getPlayer();
//int value = 0;
String breakmsg = ChatColor.GREEN + "You gained " + ChatColor.GOLD + value + ChatColor.GREEN + " points for collecting " + ChatColor.AQUA + b.getType() + ChatColor.GREEN + ".";
#SuppressWarnings("deprecation")
int itemID = p.getItemInHand().getTypeId();
if (b.getType() == Material.DIAMOND_ORE) {
if (itemID == 257 || itemID == 278) {
//value = 5;
setValue(5);
int points = getConfig().getInt("players." + p.getUniqueId() + ".points");
getConfig().set("players." + p.getUniqueId() + ".points", points + value);
saveConfig();
startScoreboard();
e.getPlayer().sendMessage(breakmsg);
}
}
if (b.getType() == Material.GOLD_ORE) {
if (itemID == 257 || itemID == 285 || itemID == 278) {
//value = 3;
setValue(3);
int points = getConfig().getInt("players." + p.getUniqueId() + ".points");
getConfig().set("players." + p.getUniqueId() + ".points", points + value);
saveConfig();
startScoreboard();
e.getPlayer().sendMessage(breakmsg);
}
}
}
You could wrap that logic in a private function.
private String generateBreakMsgFrom(Block block, int value) {
return ...
}
Then within the if statements rather than setting value you can do:
breakmsg = generateBreakMsgFrom(b, 5);
Please note that you could and should probably also simply set the message after the if statements, but still you want to extract the message generation logic into a private function.
I would really recommend you to read Clean Code. Your function is very long, it is doing multiple things, it has a lot of magic numbers and quite a lot of code duplication...
EDIT: Since you declared int value in your function I haven't realized that it was an instance variable, therefore.
private String generateBreakMsgForBlock(Block block) {
return ... //you can use value from here once properly set
}
I am working on a multithreaded project in which I need to randomly find columns that I will be using in my SELECT sql and then I will be executing that SELECT sql query.
After finding those columns-
I need to see whether the id is between the valid range, if it in between the Valid Range, then loop around the resultset using those columns from the columnsList and get the data back and store in a variable.
else if id is not in the valid range, I need to check I am not getting any data back from the resultset. But somehow if I am getting the data back and flag is true to stop the program, then exit the program. Else if I am getting the data back but flag is false to stop the program, then count how many of those happening.
Below is my code-
private volatile int count;
#Override
public void run() {
.....
final String columnsList = getColumns(table.getColumns());
....
rs = preparedStatement.executeQuery();
....
if (Read.endValidRange < id && id < Read.startValidRange) {
while (rs.next()) {
for(String column: columnsList.split(",")) {
System.out.println(column + ": " + rs.getString(column));
}
}
} else {
if(rs.next() && Read.flagTerminate) {
System.exit(1);
} else {
count++;
}
}
....
}
/**
* A simple method to get the column names in the order in which it was
* inserted
*
* #param columns
* #return
*/
private String getColumns(final List<String> columns) {
List<String> copy = new ArrayList<String>(columns);
Collections.shuffle(copy);
int rNumber = random.nextInt(columns.size());
List<String> subList = copy.subList(0, rNumber);
Collections.sort(subList, new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
return columns.indexOf(o1) < columns.indexOf(o2) ? -1 : 1;
}
});
return StringUtils.join(subList, ",");
}
Problem Statement-
I am not able to understand how should I iterate through the resultset as every time I will be having different columns in my SELECT sql depending on what is getting generated. And apart from that how can I make it more cleaner in the if else loop.
OK..
You can have the Randomly generated columns saved in a String array..and then while iterating via resultset you use that array...as follows:
UPDATE
You should not include those columns in select statement..Instead you should select all columns in select statement using *...and then get the value of that column in rs.next() loop...
rs = con.executeQuery("Select * from tablename");
while(rs.next())
{
for (String col : columnsList )
{
System.out.print(rs.get(col));
}
System.out.print("\n");
}
UPDATE1
You need your critical code section written within run() to be wrapped in synchronized block so as to avoid Race Condition as follows:
private volatile int count;
#Override
public void run() {
.....
while (!Read.flagTerminate)
{
synchronized(this)
{
if (!Read.flagTerminate)
{
String columnsList = getColumns(table.getColumns());
....
rs = preparedStatement.executeQuery();
....
if (Read.endValidRange < id && id < Read.startValidRange)
{
while (rs.next())
{
for(String column: columnsList.split(","))
{
System.out.println(column + ": " + rs.getString(column));
}
}
}
else
{
while (rs.next())
{
count++;
}
}
}
}
}
System.exit(0);//it implies that flag = true;
....
}
/**
* A simple method to get the column names in the order in which it was
* inserted
*
* #param columns
* #return
*/
private String getColumns(final List<String> columns) {
List<String> copy = new ArrayList<String>(columns);
Collections.shuffle(copy);
int rNumber = random.nextInt(columns.size());
List<String> subList = copy.subList(0, rNumber);
Collections.sort(subList, new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
return columns.indexOf(o1) < columns.indexOf(o2) ? -1 : 1;
}
});
return StringUtils.join(subList, ",");
}
What about this:
if (Read.endValidRange < id && id < Read.startValidRange) {
while (rs.next()) {
for (String column : columnsList.split(",")) {
System.out.println(column + ": " + rs.getString(column));
}
}
} else if (rs.next()) {
if (Read.flagTerminate) {
System.exit(1);
} else {
count++;
}
}
I have also updated the if-else conditions as per my understanding of the question.