LinkedHashMap with ArrayList - How to load ArrayList? - java

I am fairly new to Java and am trying to load a LinkedHashMap that contains an ArrayList of values. I am trying to load the values from a query result from an API based query result (Salesforce).
Here is the error: "Cannot refer to a non-final variable breakdown inside an inner class defined in a different method" - the breakdown variable is underlined in red giving this message, Ive noted the line in concern below.
CODE
public LinkedHashMap<String, ArrayList<String>> sfFundIdsByContact;
public ArrayList<String> getFundsIDsForContact(Contact aContact)
{
QueryResult queryResults = null;
ArrayList<String> ids = new ArrayList<String>();
int index = 0;
Boolean done = false;
String contactid = aContact.getId();
String SCCPBId = null;
if(sfFundIdsByContact == null || sfFundIdsByContact.size() <= 0){
//Do the Salesforce API CALL and Return the results
...
while (! done)
{
SObject[] records = queryResults.getRecords();
for ( int i = 0; i < records.length; ++i )
{
if(sfFundIdsByContact.containsKey(breakdown.getSalesConnect__Contact__c())){
sfFundIdsByContact.get(breakdown.getSalesConnect__Contact__c()).add(breakdown.getId());
} else {
//Line below in the add(breakdown.getId() - contains the error
sfFundIdsByContact.put(breakdown.getSalesConnect__Contact__c(), new ArrayList<String>() {{ add(breakdown.getId()); }});
}
}
All suggestions are appreciated.

In your else block, instead of:
new ArrayList<String>() {{ add(**breakdown.getId()**); }}
you can use:
new ArrayList<String>(Arrays.asList(breakdown.getId())
or, since you just want a single element ArrayList, you can use Collections.singletonList that avoids the creation of temporary varargs array:
new ArrayList<String>(Collections.singletonList(breakdown.getId())
The { ... } after the new ArrayList<>() creates an anonymous subclass of ArrayList, which is an inner class only. Inside an inner class you cannot access non-final local variables.

You can ease the code by always retrieving the List value in the for loop, then if it is null create a new one and add it to your Map, otherwise add the value to the list.
for (int i = 0; i < records.length; i++) {
List<String> value = sfFundIdsByContact.get(breakdown.getSalesConnect__Contact__c());
if (value == null) {
value = new ArrayList<String>();
sfFundIdsByContact.put(breakdown.getSalesConnect__Contact__c(), value);
}
value.add(breakdown.getId());
}
As a recommendation, change the definition of
LinkedHashMap<String, ArrayList<String>> sfFundIdsByContact
to
Map<String, List<String>> sfFundIdsByContact
Refer to What does it mean to "program to an interface"?

Related

Error while checking specific value at index is null

I have below list defined,
List<BigDecimal> empList = new ArrayList<BigDecimal>();
And as per below code if condition throws error The type of the expression must be an array type but it resolved to List
for(int i1=0;i1<12;i1++) {
if(empList[i1]==null){
empList[i1]= new BigDecimal("0.00");
}
}
The same code works well in Groovy but does not work in Java.
Looks like a syntax error . In java list are accessed as
empList.get(i1)
and
empList.set(i1,new BigDecimal("0.00"))
or you are free to use array instead of List but in this case you will have to define the array length which stays fixed.
BigDecimal[] empList = new BigDecimal[10];
It has to be :
for (int i1 = 0; i1 < 12; i1++) {
if (empList.get(i1) == null) {
empList.set(i1, new BigDecimal("0.00"));
}
}
A list collection needs has its own methods. Use those.

JAVA Get each value of arraylist

I have one arraylist that contain two list
like this
[[asd, asswwde, efef rgg], [asd2223, asswwd2323e, efef343 rgg]]
My Code is
ArrayList<String> create = new ArrayList<String>();
ArrayList<String> inner = new ArrayList<String>();
ArrayList<String> inner1 = new ArrayList<String>();
inner.add("asd");
inner.add("asswwde");
inner.add("efef rgg");
inner1.add("asd2223");
inner1.add("asswwd2323e");
inner1.add("efef343 rgg");
create.add(inner.toString());
create.add(inner1.toString());
i have to get all value one by one of every index of that arraylist
So what is the best way to get these all value one by one.
I am using JAVA with Eclipse Mars.
Just use two nested loops:
List<List<Object>> list = ...;
for (List<Object> subList : list) {
for (Object o : subList) {
//work with o here
}
}
You may also want to consider replacing the inner lists by proper objects.
You want to loop through the outside ArrayList and then loop through each ArrayList within this ArrayList, you can do this by using the following:
for (int i = 0; i < outerArrayList.size(); i++)
{
for (int j = 0; j < outerArrayList.get(i).size(); j++)
{
String element = outerArrayList.get(i).get(j);
}
}
Here is another verison you may find easier to understand, but is essentially the same:
for (int i = 0; i < outerArrayList.size(); i++)
{
ArrayList<String>() innerArrayList = outerArrayList.get(i)
for (int j = 0; j < innerArrayList.size(); j++)
{
String element = innerArrayList.get(j);
}
}
or alternatively again using a foreach loop:
for (ArrayList<String> innerArrayList : outerArrayList)
{
for (String element : innerArrayList)
{
String theElement = element;
}
}
It might be worth noting that your ArrayList appears to contain different types of elements - is this definitely what you wanted to do? Also, make sure you surround your strings with "" unless they are variable names - which it doesn't appear so.
EDIT: Updated elements to type String as per your update.
I would also recommend you change the type of your create ArrayList, like below, as you know it will be storing multiple elements of type ArrayList:
ArrayList<ArrayList> create = new ArrayList<ArrayList>();
Try to use for loop nested in foreach loop like this:
for(List list : arrayListOfList)
{
for(int i= 0; i < list.size();i++){
System.out.println(list.get(i));
}
}
I'm not sure if the data structures are part of the requirements, but it would be better constructed if your outer ArrayList used ArrayList as the generic type.
ArrayList<ArrayList<String>> create = new ArrayList<ArrayList<String>>();
ArrayList<String> inner = new ArrayList<String>();
ArrayList<String> inner1 = new ArrayList<String>();
...
create.add(inner);
create.add(inner1);
Then you could print them out like this:
for(List list : create) {
for (String val : list) {
System.out.println(val);
}
}
Othewise, if you stick with your original code, when you add to the outer list you are using the toString() method on an ArrayList. This will produce a comma delimited string of values surrounded by brackets (ex. [val1, val2]). If you want to actually print out the individual values without the brackets, etc, you will have to convert the string back to an array (or list) doing something like this:
for (String valList : create) {
String[] vals = valList.substring(1, val.length() - 1).split(",");
for (String val : vals) {
System.out.println(val.trim());
}
}

Why am I unable to assign an embedded ArrayList<Integer> to a locally declared ArrayList<Integer>?

Sorry if the title is not clear, I'm not very good with programming jargon.
I have 2 string ArrayLists and an integer ArrayList obtained from one method which is passed to a separate method through the collection LinkedHashMap< String, List< String>>. However, when I try to set the integer ArrayList into a empty ArrayList declared in the receiving method, it shows the syntax error: "incompatible types: List< String> cannot be converted to List< Integer>".
Starter Method:
public static void main(String[] args) {
try{
LinkedHashMap lhm = new LinkedHashMap();
List<String> listEPC = new ArrayList<String>();
List<String> listTimeStamp = new ArrayList<String>();
List<Integer> listAntenna = new ArrayList<Integer>();
String tagID = "EQ5237";
String TimeStampStr = "12:23:22";
int tagAntenna = 2;
listEPC.add(tagID);
listTimeStamp.add(TimeStampStr);
listAntenna.add(tagAntenna);
lhm.put("epcs", listEPC);
lhm.put("timestamps", listTimeStamp);
lhm.put("antennas", listAntenna);
insertData insert = new insertData();
insert.insertData(lhm); //send map with values to new method
}catch(Exception e){
e.printStackTrace();
}
}
Receiving Method:
public class insertData {
public void insertData(LinkedHashMap<String, List<String>> readMap) {
List<String> listEPC = new ArrayList<String>();
List<String> listTimeStamp = new ArrayList<String>();
List<Integer> listAntenna = new ArrayList<Integer>();
String EPC = null;
String TimeStamp = null;
Integer Antenna = null;
listEPC = readMap.get("epcs");
listTimeStamp = readMap.get("timestamps");
listAntenna = readMap.get("antennas"); //error message here
for(int i=0; i<readMap.size(); i++){
EPC = listEPC.get(i);
TimeStamp = listTimeStamp.get(i);
Antenna = listAntenna.get(i);
System.out.println("Entry " + i );
System.out.println("Values: " + EPC + TimeStamp + Antenna);
}
}
}
This code works only if I change all instances of integers to strings, which is not what I would like in my actual code. Why is it so and how do I work around it?
You can't assign a List<String> to a List<Integer>. The elements are fundamentally different types.
You would need to construct a new List:
List<Integer> listOfIntegers = new ArrayList<>();
for (String entry : listOfStrings) {
listOfIntegers.add(Integer.valueOf(entry);
}
Of course, you also need to handle the possibility that elements of the list cannot be parsed as integers.
However, you are just throwing away type information by stuffing everything into a single map. It would be better to pass the three lists separately:
insertData(listEPC, listTimestamp, listAntenna);
and then you can have different list types in the method signature:
void insertData(
List<String> listEPC,
List<String> listTimestamp,
List<Integer> listAntenna) { ... }
I am going to include the proper answer at the bottom, but in regards to your question title, you'll have to change your method signature to:
LinkedHashmap<String, List<?>> readMap;
Then either cast the lists, which will cause an unsafe cast. eg.
List<String> listEPC = (List<String>)readMap.get("epcs");
Or cast the object.
List<?> listEPC = readMap.get("epcs");
Then in the loop cast.
EPC = (String)listEPC.get(i);
Note, these are not good solutions.
What you should have is one List that contains an object with all of the data's you need.
I can imagine the thought process went something along these lines, "I have these things, and they contain two strings and an integer. I will create a variable for each." Then you ask the question, "How do I create a collection of these things?"
The wrong answer to this question is, "I will make a list for each value, and match associated values by index." The correct answer is, "I will create a class to represent my data, and store that in a list." This is the basic essence of object orient programming (welcome to java).
First we design the class:
class EPCThing{
String EPC;
String timeStamp;
int Antennas;
public EPCThing(String tagId, String timeStamp, int antennas){
EPC=tagId;
this.timeStamp = timeStamp;
Antennas = antennas;
}
#Override
public String toString(){
return "Values: " + EPC + TimeStamp + Antenna
}
}
Now your program's main method will be something like.
List<EPCThing> things = new ArrayList<>();
String tagID = "EQ5237";
String TimeStampStr = "12:23:22";
int tagAntenna = 2;
EPCThing thing = new EPCThing(tagID, TimeStampStr, tagAntenna);
things.add(thing);
insertData insert = new insertData();
insert.insertData(things);
Then we can fix your insertData method
public void insertData(List<EPCThing> things) {
for(int i=0; i<things.size(); i++){
System.out.println("Entry " + i );
System.out.println("Values: " + things.get(i));
}
}

TreeMap using a string key and an arraylist

I am brand new to using collections, so I am confused on how to do this. I am trying to use a TreeMap to hold a word as the key and then an ArrayList to hold one or more definitions for the word.
public class Dict {
Map<String, ArrayList<String>> dic = new TreeMap<String, ArrayList<String>>();
public void AddCmd(String word, String def) {
System.out.println("Add Cmd " + word);
if(dic.get(word)==null){
dic.put(word, new ArrayList.add(def));
}
}
}
I am getting an error on "new ArrayList.add(def)". I thought this was the correct way to do this, but I am obviously wrong. Does anyone have any ideas as to what I am doing wrong?
Calling ArrayList#add returns a boolean which is not the desired value for your Map, thus getting the compiler error.
You need to insert the ArrayList and then add the element. Your code should look like this:
ArrayList<String> definitions = dic.get(word);
if (definitions == null) {
definitions = new ArrayList<String>();
dic.put(word, definitions);
}
definitions.add(def);
dic.put(word, new ArrayList.add(def)); is the culprit.
since you have declared map to take Arraylist of string as a value. the value to pass for map must be Arraylist of string.
but this line is adding a value as new ArrayList.add(def) since you are trying to create a list and adding element , add method returns boolean -> true if it can add false if it fails.
so it means value to the map is going as a boolean not as arraylist which is against the map declaration.
so use code as below
ArrayList<String> listOfString = dic.get(word);
if (listOfString == null) {
listOfString = new ArrayList<String>();
listOfString .add(def);
}
dic.put(word, listOfString );
You have to break it up, because add does not return the original ArrayList:
ArrayList<String>> NewList = new ArrayList<String>();
NewList.add(def);
dic.put(word, NewList);
You are not actually creating a new ArrayList. Try this:
ArrayList<String> newDef = new ArrayList<String();
newDef.add(def);
dic.put(word, newDef);

Array List Null Pointer Exception - Android

I am trying to create an application which retrieves the users favourite book quote however I am stuck on how to display this information back to the user. I created an ArrayList which will store all the information. However when displaying this information, I keep getting the error:
java.lang.NullPointerException
when it tries to execute the code
temp[i] = new HashMap<String,String>();
This class is shown below:
public class FavouriteQuotesActivity extends ListActivity {
static final ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>();
private void getFavorites() {
DataBaseHelper myDbHelper = new DataBaseHelper(this);
String favorites [] = myDbHelper.getFavourites();
if(list.size() > 0)
{
list.removeAll(list);
}
for(int i = 0;i < favorites.length; i++)
{
String quotes = favorites[i];
String[] quoteArray = quotes.split(":");
HashMap<String,String> temp[] = null;
temp[i] = new HashMap<String,String>();
temp[i].put("Author",(quoteArray[2]));
temp[i].put("Quote",(quoteArray[4]));
list.add(temp[i]);
}
}
Any help would be greatly appreciated.
Look at this code:
HashMap<String,String> temp[] = null;
temp[i] = new HashMap<String,String>();
You've just assigned a null value to the temp variable (which would more typically have a declaration of HashMap<String, String>[] temp) - so of course you'll get a NullPointerException when you then try to access temp[i] on the very next statement.
It's not clear why you're using an array at all in that code - why aren't you just using:
HashMap<String, String> map = new HashMap<String, String>();
map.put("Author", quoteArray[2]);
map.put("Quote", quoteArray[4]);
list.add(map);
Additionally it's unclear why you're using a map at all here, given that it will always have the same two keys. Why not create a Quote class with name and author properties? Also, using a static variable here seems like a bad idea - why doesn't getFavorites create a new list on each invocation, and return it at the end of the method?
You are declaring and using temp wrong. You don't need an array of HashMap, just a single HashMap, since list is an ArrayList<HashMap>:
HashMap<String,String> temp = new HashMap<String,String>();
temp.put("Author",(quoteArray[2]));
temp.put("Quote",(quoteArray[4]));
list.add(temp);
temp doesn't point to an array. You are setting it to null.
You declared the variable temp as an array (by writing HashMap temp[]).
Without being it an actual array, you can't set any elements.

Categories