I have seen this 2d Arraylist Question multiple times on SO, but don't understand why this doesn't work for my Language App.
I have an arraylist (called stage1) containing multiple arraylists (each is called entry) The System.out.println("In switch: this is entry" + entry); displays the database values correctly so I am sure that the query string elsewhere is correct (e.g. [In switch: this is entry[water, aqua, C:\Users\Username\Documents\NetBeansProjects\LanguageApp\src\Images\Categories\Food images\water.png])
But when I add entry to stage 1 and try to access it via stage1.get(0).get(0) I get the error "Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0" which is why I tested if stage1 is empty. The other trace statement confirms that stage1 is null even after entries are added.
ArrayList<List<String>> stage1 = new ArrayList<>();
ArrayList<String> entry = new ArrayList<>();
int count = 0;
//words is an Observable List of all words relating to a specific category and langage
for (Words k : words) {
String eng = k.getEnglishWord();
String trans = "";
switch (lang) {
case "spanish":
trans = k.getSpanishWord();
break;
case "french":
trans = k.getFrenchWord();
break;
case "german":
trans = k.getGermanWord();
break;
}
String pic = k.getPicture();
entry.add(eng);
entry.add(trans);
entry.add(pic);
System.out.println("This is entry" + entry);
stage1.add(entry);
entry.clear();
if(stage1.size()!=0){ System.out.println("Stage1 " + stage1.get(0).get(0));
}
else {System.out.println("IT IS NULL");}
}
You are using single object at each time that's why it gives index out of bounds exception
Just place your arraylist into the for loop
ArrayList<String> entry = new ArrayList<String>();
for (int i = 0; i < 5; i++) {
//put you code here
ArrayList<String> entry = new ArrayList<String>();
entry.add("sd");
entry.add("sd");
entry.add("sd");
System.out.println("This is entry" + entry);
stage1.add(entry);
//entry.clear();
if(stage1.size()==0){ System.out.println("Stage1 " + stage1.get(0).get(0));
}
else {System.out.println("IT IS NULL");}
}
This will give's you desired output.
Every object in Java are reference Object. When you pass an object trought parameters of function, you pass the reference. If you modify the object inside or outside the method you will modify the object in and or out of the function.
I suggest you to take a look to it to clear your mind about all this.
Is Java "pass-by-reference" or "pass-by-value"?
Now, to solve your problem, you can reinstanciate you entre with entry = new ArrayList(); and the begiining of each loop and remove the entry.clear();.
ArrayList<List<String>> stage1 = new ArrayList<>();
ArrayList<String> entry = null;
int count = 0;
//words is an Observable List of all words relating to a specific category and langage
for (Words k : words) {
entry = new ArrayList<>();
String eng = k.getEnglishWord();
String trans = "";
switch (lang) {
case "spanish":
trans = k.getSpanishWord();
break;
case "french":
trans = k.getFrenchWord();
break;
case "german":
trans = k.getGermanWord();
break;
}
String pic = k.getPicture();
entry.add(eng);
entry.add(trans);
entry.add(pic);
System.out.println("This is entry" + entry);
stage1.add(entry);
//entry.clear();
if(stage1.size()!=0){ System.out.println("Stage1 " + stage1.get(0).get(0));
}
else {System.out.println("IT IS NULL");}
}
Related
I only want to check for:
if (lore.contains("§eSigned of ")) {
but it doesn't get that it does contain "§eSigned of "
I wrote a Minecraft Command /sign you can add a lore to an item ("Signed of playerrank | playername").
Then i wanted to add an /unsign command to remove this lore.
ItemStack is = p.getItemInHand();
ItemMeta im = is.getItemMeta();
List<String> lore = im.hasLore() ? im.getLore() : new ArrayList<String>();
if (lore.contains("§eSigned of " + getChatName(p))) { // this line is important!
for (int i = 0; i < 3; i++) {
int size = lore.size();
lore.remove(size - 1);
}
im.setLore(lore);
is.setItemMeta(im);
p.setItemInHand(is);
sendMessage(p, "§aThis item is no longer signed");
} else {
sendMessage(p, "§aThis item is not signed!");
}
return CommandResult.None;
Everything works fine until you e.g. change your name. than you can't remove the sign because getChatName(p) has changed.
To fix this i only want to check
if (lore.contains("§eSigned of ")) {
but than it doesn't get it and returns false. (it says lore does not contain "§eSigned of ")
I tried a lot but it only works with the string "§eSigned of " and getChatName(p).
As the documentation "contains" searches for the specific string so it should work as I thought right?
Add:
getChatName(p) returns the rank of the player and the playername like: "Member | domi"
sendMessage(p, "") sends a simple message in the Minecraft chat
The problem you run into is that contains(String) looks for a matching string. What you search for is a check if any string in the list starts with "§eSigned of ".
I would suggest adding a function isSignedItem like this:
private boolean isSignedItem(List<String> lore) {
for (String st : lore)
if (st.startsWith("§eSigned of "))
return true;
return false;
}
and then to use this function to check if the item is signed or not:
[...]
List<String> lore = im.hasLore() ? im.getLore() : new ArrayList<String>();
if (isSignedItem(lore)) { // this line is important!
for (int i = 0; i < 3; i++) {
int size = lore.size();
lore.remove(size - 1);
}
[...]
I'm in the process of building a basic database using csv files, and i'm currently testing the select function out when i ran into something strange.
private ArrayList<Record> selectField(String selectTerm)
{
Log.log("Selection " + selectTerm,2,"DB_io");
ArrayList<Record> ret = new ArrayList<Record>();
if (titleRow.values.contains(selectTerm))
{
Log.log("Adding values to " + selectTerm);
int ordinal = titleRow.values.indexOf(selectTerm);
Log.log("Ordinal " + ordinal);
List<String> tempList = new ArrayList<String>();
for (Record r : data)
{
List<String> tempList = new ArrayList<String>();
tempList.add(r.values.get(ordinal));
Record s = new Record(tempList);
ret.add(s);
tempList.clear();
}
Log.log("Number of records in ret " + ret.size());
for (Record t : ret)
{
Log.log(t.toString());
}
}
else
{
Log.log("keyField does not contain that field");
return null;
}
Log.log("Values " + ret.toString());
return ret;
}
When i do this, the part where it logs t.ToString() shows the record to be empty, whereas if i log it before tempList.clear(), it shows the record to be containing data like it should.
If i move the tempList declaration into the Record r : data loop, then it works fine and the Record t : ret loop works outputs the contents of the record like it should
Why is this?
Edit : Record class
public class Record
{
List<String> values = new ArrayList<String>();
public Record(List<String> terms)
{
this.values = terms;
}
public Record(String[] s)
{
this.values = Arrays.asList(s);
}
public String toString()
{
return values.toString();
}
}
Your Record instance holds a reference to the ArrayList instance you passed to its constructor. Therefore, when you call tempList.clear(), you clear the same List that your Record instance is holding a reference to.
You shouldn't call tempList.clear(), since you are creating a new ArrayList in each iteration of your loop anyway.
you are referencing object from more than one place and clear method is cleaning object by setting its reference to null:
instead of ret.add(s); you can use ret.add(s.clone());
Search by id method:
public class ClientsDetailsList {
public ArrayList <ClientDetails> aListOfClientDetails;
public ClientDetails getClientDetails(String givenID) {
boolean found = false;
int index = 0;
for(;index<aListOfClientDetails.size();index++){
if((aListOfClientDetails.get(index).ClientID.equals(givenID)))
found = true;
}
if(found)
return aListOfClientDetails.get(index);
else return null;
}
}
aListOfClientDetails List format It reads a file and creates a list of ClientDetails.
[IC-x00042W Ms LQ Bethea 205, Willis Road Bolton BO5 1DQ 2000000007 2000100037 2006200319,
IC-x00033D Mr R Bowie 119, Thatcher Way Glasgow GL9 5SX 2006000016 2003100008 2005300001,
IC-x00013A MS GRV Blackwell 209, Drunk Road Hawick HK8 1MY 2006000009 2004100014 2003200304,
IC-x00018O Ms NAP Wallis 244, Grubb Lane Durham DU4 4ZX 2000000006 2003100012 2006200305]
One line is an object of the list. With the method above I try to return an object of the list found by ID (e.g. first token IC-x00042W). However when I run this in my main method it returns Only the first object.(IC-x00042W/Ms/LQ/Bethea/205, Willis Road/Bolton/BO5.....)
If I search by id of another object it returns null.
Source of ClientDetailsList:
The txt file has the following data:
IC-x00042W/Ms/LQ/Bethea/205, Willis Road/Bolton/BO5 1DQ/2000000007/2000100037/2006200319#
IC-x00033D/Mr/R/Bowie/119, Thatcher Way/Glasgow/GL9 5SX/2006000016/2003100008/2005300001#
IC-x00013A/MS/GRV/Blackwell/209, Drunk Road/Hawick/HK8 1MY/2006000009/2004100014/2003200304#
IC-x00018O/Ms/NAP/Wallis/244, Grubb Lane/Durham/DU4 4ZX/2000000006/2003100012/2006200305#
IC-x00037N/Miss/DOD/Burke/272, Ambrose Lane/Cambridge/CB2 2XD/2005000003/2001100020#
IC-x00039A/Dr/X/Salter/285, Bannister Road/Sea Palling/SP2 6GW/2000000002/2005100029/2005200306#
IC-x00011I/MR/R/Reece/104, Bannister Lane/Cromer/CR0 6LD/2005000012/2003100001/2001200300#
IC-x00025V/Mr/P/Abbott/163, Drunk Lane/Hunstanton/HU1 1UR/2003000029/2004100017#
IC-x00008L/Dr/P/Runyon/150, Tick Tock Way/Swindon/SW8 4OJ/2004000005/2006100005/2001200316#
IC-x00028F/MR/X/Watt/267, Malton Road/Cambridge/CB4 1PQ/2004100016/2004200312#
IC-x00031X/Mr/S/Lorenz/276, Tick Tock Way/London/LN9 7ID/2005000023/2005100007#
IC-x00020C/Mr/LNV/Mcmillan/44, Drunk Street/London/LN6 1RG/2001000019#
IC-x00015H/Mr/TQZ/Dubose/201, Drunk Road/London/LN4 5RA/2003000026/2006100028/2000200307#
//Creates ClientsDetailsList from source file
public static ClientsDetailsList readFile(File inputFile) throws IOException{
ArrayList <String> clientData = new ArrayList<String>();
ArrayList <ClientDetails> cdList = new ArrayList<>();
ArrayList <PolicyList> arrayofPolsLists = new ArrayList<>();
//Lists of ClientDetails fields
ArrayList <Name> clientName = new ArrayList<>();
ArrayList <String> clientID = new ArrayList<String>();
ArrayList <Address> clientAddress = new ArrayList<>();
// Lists of Name class fields
ArrayList <String> clientTitle = new ArrayList<String>();
ArrayList <String> clientInitials = new ArrayList<String>();
ArrayList <String> clientSurname = new ArrayList<String>();
//Lists of Address class fields
ArrayList <String> clientStreet = new ArrayList<String>();
ArrayList <String> clientCity = new ArrayList<String>();
ArrayList <String> clientPostCode = new ArrayList<String>();
ArrayList <ArrayList <Policy>> list = new ArrayList<ArrayList<Policy>>();
Scanner fileScan = new Scanner(inputFile);
fileScan.useDelimiter("#");
int i =0;
//Reading the file
while(fileScan.hasNext()){
clientData.add(fileScan.next());
Scanner cdScan = new Scanner(clientData.get(i));
cdScan.useDelimiter("/");
ArrayList <String> tokens = new ArrayList<String>();
ArrayList <Policy> clientPolicyNo = new ArrayList<>();
while(cdScan.hasNext()){
tokens.add(cdScan.next());
}
clientID.add(tokens.get(0));
clientTitle.add(tokens.get(1));
clientInitials.add(tokens.get(2));
clientSurname.add(tokens.get(3));
clientStreet.add(tokens.get(4));
clientCity.add(tokens.get(5));
clientPostCode.add(tokens.get(6));
boolean whileController = true;
while(whileController){
clientPolicyNo.add(new Policy(tokens.get(7)));
switch(tokens.size()){
case 9 : clientPolicyNo.add(new Policy(tokens.get(8)));
break;
case 10: clientPolicyNo.add(new Policy(tokens.get(8)));
clientPolicyNo.add(new Policy(tokens.get(9)));
break;
case 11: clientPolicyNo.add(new Policy(tokens.get(8)));
clientPolicyNo.add(new Policy(tokens.get(9)));
clientPolicyNo.add(new Policy(tokens.get(10)));
break;
}
whileController=false;
}
list.add(clientPolicyNo);
i++;
}
//Adding policy lists
for(int j =0; j<clientID.size();j++){
arrayofPolsLists.add(new PolicyList());
arrayofPolsLists.get(j).aListOfPolicies=list.get(j);
}
//Creating Name objects
for(int j =0;j<clientID.size();j++){
clientName.add(new Name());
clientName.get(j).Title = clientTitle.get(j);
clientName.get(j).Initials = clientInitials.get(j);
clientName.get(j).Surname = clientSurname.get(j);
}
//Creating Address objects
for(int j =0;j<clientID.size();j++){
clientAddress.add(new Address());
clientAddress.get(j).street = clientStreet.get(j);
clientAddress.get(j).city = clientCity.get(j);
clientAddress.get(j).postcode = clientPostCode.get(j);
}
//Creating ClientDetails
for(int j =0;j<clientID.size();j++){
cdList.add(new ClientDetails());
cdList.get(j).ClientID = clientID.get(j);
cdList.get(j).fullName = clientName.get(j);
cdList.get(j).fullAddress = clientAddress.get(j);
cdList.get(j).clientsPolicies = arrayofPolsLists.get(j);
}
//Creating a ClientDetailsList object
ClientsDetailsList ClientDetList = new ClientsDetailsList();
ClientDetList.aListOfClientDetails = cdList;
return ClientDetList;
}
ClientDetails class has 4 fields:
public String ClientID;
public Name fullName;
public Address fullAddress;
public PolicyList clientsPolicies;
Main method
File clientsFile = new File("ClientDetailsInput");
InputData e = new InputData();
ClientsDetailsList testList = new ClientsDetailsList();
testList = e.readFile(clientsFile);
System.out.println(testList.getClientDetails("IC-x00013A"));
Put a break after found = true;, for example...
public ClientDetails getClientDetails(String givenID) {
boolean found = false;
int index = 0;
for(;index<aListOfClientDetails.size();index++){
if((aListOfClientDetails.get(index).ClientID.equals(givenID))) {
found = true;
break;
}
}
if(found)
return aListOfClientDetails.get(index);
else return null;
}
Or you could simplify it further, by doing away with the need for the index at all, for example
public ClientDetails getClientDetails(String givenID) {
boolean found = false;
int index = 0;
ClientDetails details = null;
for (ClientDetails check : aListOfClientDetails) {
if(check.ClientID.equals(givenID)) {
details = check;
break;
}
}
return details;
}
Updated
After actually been able to read the data, I added
String check = aListOfClientDetails.get(index).ClientID;
System.out.println(givenID + " = " + check);
if ((check.equals(givenID))) {
to the search list and it printed...
IC-x00013A = IC-x00042W
IC-x00013A =
IC-x00033D
IC-x00013A =
IC-x00013A
IC-x00013A =
IC-x00018O
IC-x00013A =
IC-x00037N
IC-x00013A =
IC-x00039A
IC-x00013A =
IC-x00011I
IC-x00013A =
IC-x00025V
IC-x00013A =
IC-x00008L
IC-x00013A =
IC-x00028F
IC-x00013A =
IC-x00031X
IC-x00013A =
IC-x00020C
IC-x00013A =
IC-x00015H
...which freaked me out, until I realised that the ID's were prefixed with a new line character...!
So what I did was add trim to each result from the tokens in the read method...
clientID.add(tokens.get(0).trim());
(I did it for each line, just haven't shown), which then lead to
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 13, Size: 13
at java.util.ArrayList.rangeCheck(ArrayList.java:638)
at java.util.ArrayList.get(ArrayList.java:414)
at testsearch.TestSearch$ClientsDetailsList.getClientDetails(TestSearch.java:47)
at testsearch.TestSearch.main(TestSearch.java:23)
Which is what I expected should happen in your search method...
If we have a closer look at the search loop...
for(;index<aListOfClientDetails.size();index++){
if((aListOfClientDetails.get(index).ClientID.equals(givenID)))
found = true;
}
You should be able to see, that regardless of the state of found, the index will ALWAYS be equal to aListOfClientDetails.size() at the end of the loop, as there is no other exit condition to the loop that takes found into consideration...
Which takes me back to my original suggestions...
Never discount the power of a simple System.out.println statement to check your sanity and a good debugger...
Debugging would have helped i guess.
At the end you are returning
return aListOfClientDetails.get(i);
But you should get index "index" instead of "i" that was never initiated as far as i see.
So replace that with
return aListOfClientDetails.get(index);
And of course dont forget to leave the loop when you find something so index stays the right index.
Or just return the object right after you found it instead of setting found to true.
And last but not least: I dont know ClienID so I cant tell from here but if it does not implement the equals function the you actually will not get it work the way you want. So check what it does and perhaps override it.
Setting the Scanner's delimiter to '#' or '/' causes the line separators \n (whatever it is on your system) to remain in the data. So, some next() method call will eventually produce a String value with a leading \n, which is bound to happen for all IDs from the second one up, if the line structure is aligned with the '#' signs.
The code you have for parsing is extremely complex. I'd advocate to read lines (\n-delimited) and handle one line at a time, using
String[] tokens = line.split( "/" );
and assigning the strings to the destination fields of one object. Avoid the many lists - this only confuses matters.
So I tried finding a tutorial on how to do this but nothing gets this complicated. This is the first I am learning of HAshMaps so I am sure my solution should be easy, but I don't know how to do it.
I am trying to use an Array to populate a HashMap, and when I run the program my print out shows up null, which indicates that it isn't populating for me. Been working on this for two days, and am really lost and confused.
I am trying to get my key "expenses" to be valued with a "type".
Edit: I would like my case two to be a printout of
1: groceries
2: Entertainment
3: Etc.....
public static void main(String[] args) throws FileNotFoundException, IOException
{
// TODO code application logic here
// HashMap<String, String> map = new HashMap<String, String>();
HashMap<String, List<Expenses>> map = new HashMap<>();
List <Expenses> expenseType = new ArrayList();
double amount, totalAmount;
int cmd, year, month, date;
String type, resp;
totalAmount = 0;
String fname = JOptionPane.showInputDialog("Enter the name of the budget file, none if no file");
if (fname.compareTo("none") !=0)
{
FileInputStream ist = new FileInputStream(fname);
ObjectInputStream ifile = new ObjectInputStream(ist);
}
boolean done = false;
while(!done)
{
resp = JOptionPane.showInputDialog("Enter a command from: \n"
+ "\t1:Add a new deduction\n" //think its done
+ "\t2:Add a new expense\n" //this is done, but could be made better wit
+ "\t3:Add a deposit\n" //This is done
+ "\t4:Deduction options\n"
+ "\t5:Expense Options\n"
+ "\t6:Total balances in bank\n"
+ "\t7:quit");
cmd = Integer.parseInt(resp);
switch(cmd)
{
case 1:
break;
case 2:
//Give the option to add new spending occurence.
//Give option to choose from array of spending types.
resp = JOptionPane.showInputDialog("Enter a command from: \n"
+ "\t1: Create a new expense\n" //done
+ "\t2: Choose from expense list\n"
+ "\t3:quit");
int cmd2 = Integer.parseInt(resp);
switch (cmd2)
{
case 1:
type = JOptionPane.showInputDialog("Enter the type of the expense:");
resp = JOptionPane.showInputDialog("Enter the amount of the expense:");
amount = Double.parseDouble(resp);
resp = JOptionPane.showInputDialog("Enter the year of the expense:");
year = Integer.parseInt(resp);
resp = JOptionPane.showInputDialog("Enter the month of the expense:");
month = Integer.parseInt(resp);
resp = JOptionPane.showInputDialog("Enter the date of the expense:");
date = Integer.parseInt(resp);
// List<Expenses> expenses = map.get(type);
// Does the map have a List for type?
if (expenseType == null) {
// No. Add one.
expenseType = new ArrayList<>();
map.put(type, expenseType);
}
Expenses e = new Expenses(type, amount, year, month, date);
expenseType.add(e);
// map.put(type, new ArrayList(expenses));
map.put(type, expenseType);
break;
case 2:
//Use a hashmap to search through the ArrayLIst and print out options.
//How do I populate the HashMap?
type = null;
List<Expenses> typelist = map.get(type); //reads from map
System.out.println(typelist);
break;
}
}
}
}
}
Please don't use raw types. And, if I understand you, then you want something like
Map<String, List<Expenses>> map = new HashMap<>();
Then, to add to the List in the Map - use something like
List<Expenses> expenses = map.get(type);
// Does the map have a List for type?
if (expenses == null) {
// No. Add one.
expenses = new ArrayList<>();
map.put(type, expenses);
}
Expenses e = new Expenses(type, amount, year, month, date);
expenses.add(e);
1) You should have this line
map.put(new String(type),expenses);
instead of
map.put(expenses, new String(type));
to get value from hashmap using key i.e. type.
2) Also remove double quotes from
List<Expenses> typelist = map.get("type");
to pass variable type.
I am using temboo to get all the events for a calendar. However, i am trying to create a hashtable of the events and the days. but the for loop says its a null pointer exception even though the program is actually able to access that ith element. I have even printed it and the i is less than the size of the array. Here is the snippet code: Error is in the second line of the for loop.Errr occurs when i = 23, but items.size is 41.
GetAllEvents getAllEventsChoreo = new GetAllEvents(session);
// Get an InputSet object for the choreo
GetAllEventsInputSet getAllEventsInputs = getAllEventsChoreo.newInputSet();
// Set inputs
getAllEventsInputs.set_AccessToken(accessToken);
getAllEventsInputs.set_ClientID(clientID);
getAllEventsInputs.set_ClientSecret(clientSecret);
getAllEventsInputs.set_CalendarID(callIDs[0]);
// Execute Choreo
GetAllEventsResultSet getAllEventsResults = getAllEventsChoreo.execute(getAllEventsInputs);
results = getAllEventsResults.get_Response();
System.out.println(results);
root = jp.parse(results);
rootobj = root.getAsJsonObject();
JsonArray items = rootobj.get("items").getAsJsonArray();
System.out.println("Abour to enter the for loop\nItems:\n"+items.toString());
System.out.println("****************************\nEnter the for loop");
System.out.println("iems Size: "+items.size());
System.out.println(items.get(23).toString());
for(int i = 0;i < items.size();i++)
{
System.out.println("i: "+i);
String startTime = items.get(i).getAsJsonObject().get("start").getAsJsonObject().get("dateTime").getAsString();
System.out.println("startTime: "+startTime);
String dayKey = startTime.split("T")[0];
if(dayKey.equals(beginDate)==false | dayKey.equals(endDate)==false)
{
System.out.println(startTime + " not the one interested so skipping");
continue;
}
System.out.println("passed the first if in for loop");
String endTime = items.get(i).getAsJsonObject().get("end").getAsJsonObject().get("dateTime").getAsString();
String name = items.get(i).getAsJsonObject().get("summary").getAsJsonPrimitive().getAsString();
calendarEvent eventTemp = new calendarEvent(name,startTime,endTime);
if(table.containsKey(dayKey))
table.get(dayKey).add(eventTemp);
else
{
ArrayList<calendarEvent> schedule = new ArrayList<calendarEvent>();
schedule.add(eventTemp);
table.put(dayKey,schedule);
}
}
Set<String> key = table.keySet();
Iterator<String> it = key.iterator();
while(it.hasNext())
{
String keyValue = it.next();
System.out.println("Events on "+keyValue);
ArrayList<calendarEvent> temp = table.get(keyValue);
for(int j =0;j<temp.size();j++)
{
System.out.println(temp.get(j));
}
}
After breaking down the exception line, the exception occurs when I try to get the dateTime as string, the last part creates an exception.
Just because the ith element of an array exists, it does not mean that the element is not null.
Referencing a property or method of such an element will yield a NullPointerException.
If i went beyond the bounds of the array, you would get an ArrayIndexOutOfBoundsException instead.
Check indexed array elements for null before using them.
Sorry to be brief and not reference your code or other sources. I am on my phone. The likely source of your problem is pretty clear, though.