Add strings to String ArrayLists stored within an ArrayList - java

I am trying to retrieve some data from two different websites and want to store them in different arraylists for further processing. So in summary, I have 6 String arrayLists and then I have three arraylists to whom I have added these String arrayLists. I have done so to add data to the String arrayLists using a loop (please see code below). It however is not adding data to the String arrayLists in the manner I expected, obviously my logic is wrong. Just a little guidance would be much appreciated. The relevant Snippets of my code are below :
//creating the String type ArrayLists
private static ArrayList<String> m1=new ArrayList<String>();
private static ArrayList<String> re1=new ArrayList<String>();
private static ArrayList<String> ra1=new ArrayList<String>();
private static ArrayList<String> m2=new ArrayList<String>();
private static ArrayList<String> re2=new ArrayList<String>();
private static ArrayList<String> ra2=new ArrayList<String>();
//creating three ArrayLists of ArrayLists
private static ArrayList<ArrayList> arraylistM = new ArrayList<ArrayList>();
private static ArrayList<ArrayList> arraylistRe = new ArrayList<ArrayList>();
private static ArrayList<ArrayList> arraylistRa = new ArrayList<ArrayList>();
public static void main(String[] args) throws Exception
{
URL[] item=new URL[2];
item[0] = new URL("http://www.example111111.html");
item[1] = new URL("http://www.example222222.html");
arraylistM.add(m1);
arraylistM.add(m2);
arraylistRe.add(re1);
arraylistRe.add(re2);
arraylistRa.add(ra1);
arraylistRa.add(ra2);
for(int loop=0;loop<2;loop++)
{
BufferedReader in = new BufferedReader(
new InputStreamReader(
item[loop].openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
{
String withoutSpeechMarks=inputLine.replaceAll("\"", "");
String[] parts = withoutSpeechMarks.split("<span x=");
for (int i=0;i<parts.length;i++)
{
if (parts[i].contains("1>"))
{
(arraylistM.get(i)).add(parts[i].substring(13, (parts[i].length())-7));
}//get the first string array in arraylistM and add this data to it
if (parts[i].contains("2>"))
{
(arraylistRe.get(i)).add(parts[i].substring(9, (parts[i].length())-10));
}
if (parts[i].contains("3>"))
{
(arraylistRa.get(i)).add(parts[i].substring(7, (parts[i].length())-7));
}
}//end of inner for loop
} //end of while
in.close();
}
for (int i = 0; i < arraylistM.size(); i++)
{
System.out.println(arraylistM.get(i)+"||"+arraylistRe.get(i)+"||"+arraylistRa.get(i) );
}
The way I want it to be is that from the first website, the extracted results should be added to the string arrays m1, re1, ra1 and then from the second website the data should be added to the string arrays m2, re2, ra2. The data IS being added but all together and is not separated as I wish it to be.

From your description, it sounds like you should be using
arrayListM.get(loop).add( ... )
arrayListRe.get(loop).add( ... )
arrayListRa.get(loop).add( ... )
in the first loop instead of
arrayListM.get(i).add( ... )
arrayListRe.get(i).add( ... )
arrayListRa.get(i).add( ... )
Also, you should consider declaring your ArrayLists of ArrayLists as:
ArrayList<ArrayList<String>>
instead of
ArrayList<ArrayList>

It seems that you are facing issue while merging two Arraylist. You can easily join two ArrayList using addAll method.
ArrayList<String> al1=new ArrayList()<String>;
ArrayList<String> al2= new ArrayList()<String>;
al1.addAll(al2);
It would add all the elements of second arraylist to the first arraylist

Related

Creating ArrayList of objects containing ArrayLists as parameters - my code does not seem to create individual ArrayLists?

I am running into problem with a code for a text-based game. My class Locations is meant to load parameters from a "config" text file to create objects.
My current approach is:
I have created a public class with a constructor that will take the parameters of the object (location). It assigns them as this.xxx to private variables.
I have also created a public static class that parses the file, and once it has the necessary amount of parameters to create an object, it creates one by passing them to the constructor. Next, it adds that object to an ArrayList locations_list. Once all location objects were generated, the class returns the ArrayList locations_list
My static class parses the text file OK. However, when I run a test which iterates through locations_list and calls the getters for each element, the ArrayList parameters of objects are not individualized. All of the ArrayList elements return the same locations_characters.
The location_characters of all objects will have the same content, which is a list containing "characters" of all locations.
For example, if location 1 has characters 2 and 3 and location 2 has 6 and 7, my location_characters will print [2,3,6,7].
If I put a location_characters.clear(); after adding to location_list, the location_characters becomes empty for all objects.
Sample code snippets:
Public class with a constructor:
public class Locations {
private final int location_id;
private final String location_name;
private final String location_description;
private ArrayList <Integer> location_characters;
private ArrayList <Integer> location_items;
private final ArrayList <Integer> location_enter_from;
private final ArrayList <Integer> location_exit_to;
private String location_stage_name;
private final int location_stages;
private final ArrayList <String> location_stage_descriptions;
public Locations(int location_id,
String location_name,
String location_description,
ArrayList <Integer> location_characters,
ArrayList <Integer> location_items,
ArrayList <Integer> location_enter_from,
ArrayList <Integer> location_exit_to,
String location_stage_name,
int location_stages,
ArrayList <String> location_stage_descriptions) {
this.location_id = location_id;
this.location_name = location_name;
this.location_description = location_description;
this.location_characters = location_characters;
this.location_items = location_items;
this.location_enter_from = location_enter_from;
this.location_exit_to = location_exit_to;
this.location_stages = location_stages;
this.location_stage_descriptions = location_stage_descriptions;
}
... below are getters/setters....
Public static class for the loader:
public static ArrayList <Locations> load_locations() {
//These are used for parsing the text file
String line;
ArrayList <String> lines = new ArrayList<>();
//These are used to initialize local variables
int location_id = 0;
String location_name = null;
String location_description = null;
ArrayList<Integer> location_characters = new ArrayList<>();
ArrayList<Integer> location_items = new ArrayList<>();
ArrayList<Integer> location_enter_from = new ArrayList<>();
ArrayList<Integer> location_exit_to = new ArrayList<>();
String location_stage_name = null;
int location_stages = 0;
ArrayList<String> location_stage_descriptions = new ArrayList<>();
//This is used to initialize ArrayList of objects
ArrayList <Locations> location_list = new ArrayList<>();
//here goes the code for parsing the text files....
//below is a sample portion that loads i.e 2,3,4 split into ints,
//into the ArrayList location_characters....
case "location_characters":
String[] characters = values[1].split(",");
for (String character : characters) {
location_characters.add(Integer.parseInt(character));
}
i++;
break;
//continued...
//below I am passing the parameters into constructor,
//then adding the object to ArrayList location_list
}
Locations location = new Locations(location_id,
location_name,
location_description,
location_characters,
location_items,
location_enter_from,
location_exit_to,
location_stage_name,
location_stages,
location_stage_descriptions);
location_list.add(location);
i = 0;
}
}
reader.close();
}
catch (IOException e){
System.out.println("Problem reading file.");
}
return location_list;
}
I will appreciate insight and pointers to solution
Your code is incomplete, and the problem is in the code you're not showing: You're passing the same lists to all constructor calls, so all Locations objects are using the same lists for their fields.
This can be fixed by initializing Locations fields at their declarations, eg:
private List<Integer> location_characters = new ArrayList<>();
// repeat this pattern for all List fields
and not passing them lists through the constructor.
If you need to add to the list:
locationsInstance.getlocation_characters().add(foo);

How to edit the contents of an ArrayList in-place while looping [duplicate]

This question already has answers here:
How to change value of ArrayList element in java
(7 answers)
Closed 6 years ago.
Assume I have an ArrayList of Strings that holds the words, "hello" and "world". I want to add the word "java" to the end of each.
I have tried to do it while looping, but did not succeed. Please suggest me a method for the same.
The other way, I found was to create a different ArrayList and copy contents, however I don't think is efficient in terms of space.
import java.util.ArrayList;
public class EditArrayListInLoop {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("hello");
arrayList.add("world");
/* This does not work */
/*for(int i = 0;i<arrayList.size();i++)
{
arrayList.get(i) += "java";
}*/
ArrayList<String> arrayList2 = new ArrayList<String>();
for(int i = 0;i<arrayList.size();i++)
{
String test = arrayList.get(i);
test += "java";
arrayList2.add(test);
}
System.out.println(arrayList2);
}
}
test += "java"; doesn't change the content of the String returned by arrayList.get(i). It creates a new String. Strings are immutable, so there isn't any way to change the String objects within the List. You can only replace them by new String objects.
Use arrayList.set(index,newValue) to replace the i'th element of the List:
for(int i = 0;i<arrayList.size();i++)
{
arrayList.set(i,arrayList.get(i)+"java");
}
I think you should manipulate the first list only. Using an another list is not an optimal solution.
Here's the code.
Output
[hellojava, worldjava]
Code
import java.util.ArrayList;
public class EditArrayListInLoop {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("hello");
arrayList.add("world");
for(int i = 0;i<arrayList.size();i++)
arrayList.set(i, arrayList.get(i).concat("java"));
System.out.println(arrayList);
}
}
Please note that Strings are immutable. Whenever you change the content of String, you're not actually appending anything behind the scenes. You are creating a completely new String.
If the contents of your Strings are expected to change, then the advisable way is to use the StringBuilder class instead:
Documentation
The principal operations on a StringBuilder are the append and insert
methods, which are overloaded so as to accept data of any type. Each
effectively converts a given datum to a string and then appends or
inserts the characters of that string to the string builder. The
append method always adds these characters at the end of the builder;
the insert method adds the characters at a specified point.
Here's the code:
import java.util.ArrayList;
public class EditArrayListInLoop {
public static void main(String[] args) {
ArrayList<StringBuilder> arrayList = new ArrayList<StringBuilder>();
arrayList.add(new StringBuilder("hello"));
arrayList.add(new StringBuilder("world"));
for(int i = 0;i<arrayList.size();i++)
arrayList.set(i, arrayList.get(i).append("java"));
System.out.println(arrayList);
}
}
P.S.: If such synchronization is required then it is recommended that StringBuffer be used.
try using the set method.
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("hello");
arrayList.add("world");
for(int i = 0;i<arrayList.size();i++)
{
String str = arrayList.get(i);
arrayList.set(i, str + " java");
}
for(int i = 0;i<arrayList.size();i++)
{
String str = arrayList.get(i);
System.out.println(str);
}
You are looking for:
arrayList.set(i, arrayList.get(i) + "java");
More info on ArrayList: https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html

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));
}
}

What are the 2D ArrayList equivalents of these ArrayList Functions?

This is the initalization.
ArrayList<ArrayList<String>> names = new ArrayList<ArrayList<String>>();
The functions are as follow.
names.add("Amey");
and
names.set(a, "Jane");
Here is the full program that needs to be turned into a 2D ArrayList. The purpose of the program is to replace John with Jane, wherever John is.
import java.util.*;
public class Prac5twodArraylistString {
public static void main(String[] args) {
ArrayList<ArrayList<String>> names = new ArrayList<ArrayList<String>>();
names.add("Amey");
names.add("Aditya");
names.add("John");
names.add("Saideep");
names.add("Shrikar");
names.add("Sujay");
for (int a = 0; a <= (names.size()) - 1; a++) {
System.out.println(names.get(a));
}
for (int a = 0; a <= (names.size()) - 1; a++) {
if (names.get(a).equals("John")) {
names.set(a, "Jane");
}
}
for (int a = 0; a <= (names.size()) - 1; a++) {
System.out.println(names.get(a));
}
}
}
.Will you please help me with this code?
Your code won't compile. You are creating a List of a List of String and you are trying to add just a String to it instead of a List of String.
When you do names.add("anyName"); you would need to do names.add(new ArrayList<String>() {{add("name")};. But then the rest of your code won't work.
If you change
ArrayList<ArrayList<String>> names = new ArrayList<ArrayList<String>>();
for
ArrayList<String> names = new ArrayList<>();
your code will compile and work.
By my understanding I feel that your problem lies with your 2D ArrayList. The line ArrayList<ArrayList<String>> names = new ArrayList<ArrayList<String>>(); means that you variable names is actually an ArrayList of other ArrayList<String>. So your code name.add("SomeString") will show an error as the parameter expected in this method is ArrayList<String> but you are supplying it with String.
Now If you require to have an ArrayList of ArrayList Then you have to declare an new variable of ArrayList<String> Like this:
ArrayList<String> temp = new ArrayList<>();
The add the names to this temp object like this instead of the name object:
temp.add("Amey");
temp.add("Aditya");
temp.add("John");
temp.add("Saideep");
temp.add("Shrikar");
temp.add("Sujay");
Now add this temp object to the names object like this:
names.add(temp);
For printing out your contents you have to use this loop:
for(ArrayList<String> a : names){
for(String name: a){
System.out.println(name);
}
}
For replacing "John" with "Jane" you could use the following:
for(ArrayList<String> a : names){
if(a.contains("John")){
a.set(a.indexOf("John"), "Jane");
}
}

Can you help, is there something wrong in my code

I have a main class and then when I divide each element (id, name, surname, ...) then I should to save it in the list in another class called Student, and there class students. There are errors such as "method Collection.add(String[]) is not applicable". So what is the problem?
public class ProjectWork{
public static void main(String[] args) throws IOException{
Scanner fin = new Scanner(new File("data.txt"));
int i;
String str,name="",surname="",id="";
String [] midterms = new String[3];
while(fin.hasNextLine()){
str = fin.nextLine();
StringTokenizer toks = new StringTokenizer(str,"|");
while(toks.hasMoreTokens()){
id = toks.nextToken();
name = toks.nextToken();
surname = toks.nextToken();
for(i=0;i<3;i++){
midterms[i] = toks.nextToken();
}
}
Student(id,name,surname,midterms);
}
}
public static void Student(String id, String name, String surname, String[] midterms) throws IndexOutOfBoundsException{
private List<String[]> students = new ArrayList<String[]>();
students.add(id);
students.add(name);
students.add(surname);
}
}
Because, see this line:
private List<String[]> students = new ArrayList<String[]>();
It accepts Array of string, where as you are adding only String like this:
students.add(id);
So you are getting that error. Either declare students like this:
private List<String> students = new ArrayList<String>();
Or add "String" array using add method.
You've declared that you collection, students should take String arrays...
List<String[]> students = new ArrayList<String[]>();
But you are trying adding String elements to it, which are not the same thing.
Either change it so it does add String[] arrays...
List<String[]> students = new ArrayList<String[]>();
students.add(new String[]{id,name, surname});
or redecalre it to take String
List<String> students = new ArrayList<String>();
students.add(id);
students.add(name);
students.add(surname);
Based on what I understand your code is trying to do, I think you want the first one.
(ps- Local variables cannot be declared with access modifiers (ie private), you'll want to get rid of that)
Overall, you code doesn't make a lot of sense. You're calling a static method Student, which creates a List, adds some elements to it and the discards all that work when it exist. Is Student suppose to be a class?
You are trying to add String objects to a List, change this because you are not adding three arrays of type String:
private List<String> students = new ArrayList<String>();
You declare the students type as Array of String. So you should add an array to the collection.
To add id, name, surname, You can declare the collection type as String.
ie List<String> students = new ArrayList<String>();
The method should be like this:
public static void Student(String id, String name, String surname, String[] midterms) throws IndexOutOfBoundsException {
//List<String[]> students = new ArrayList<String[]>();
List<String> students = new ArrayList<String>();
students.add(id);
students.add(name);
students.add(surname);
}

Categories