I have several different types of ArrayLists.
Each stores split data from a .csv file.
//NOTE: this is for understanding, syntax may not be correct.
ArrayList<String> name = {item1, item2, item3, item4};
ArrayList<String> type = {type1, type2, type3, type4};
ArrayList<Double> price = {price1, price2, price3, price4};
ArrayList<Integer> qty = {qty1, qty2, qty3, qty4};
In my Item class I have a constructor like so,
public Items(String t, String n, Double p, Integer q){
type = t; //type mismatch : cannot convert from String to ArrayList<String>
name = n;//type mismatch : cannot convert from String to ArrayList<String>
price = p;//type mismatch : cannot convert from Double to ArrayList<Double>
qty = q;//type mismatch : cannot convert from Integer to ArrayList<Integer>
}
As you can see, I cant initialize my constructor because of different types. However, in my main method I call each variable as so,
public static void main(String[] args){
ArrayList<Items> itm = new ArrayList<Items>();
Items general = new Items();
//place each item into object itm
for(int i = 0; general.name.size(); i++)
{
itm.add(new Items(general.type.get(i), general.name.get(i), general.price.get(i); general.qty.get(i)));
} //throws no syntax errors
If I put "general.name.get(i)" for example, wouldn't Java see that as a String and not an ArrayList? How do I initialize these variables in my constructor?
EDIT: When I use general.type.get(i); I want that index from ArrayList type to equal t in the constructor. This is the same for n, p, and q.
t = general.type.get(i);
A box for eggs ... is not an egg.
A list of strings ... is not a string.
Meaning: you can't create a list of strings directly from that single string. You can only add a string into a already existing list. Like putting an egg in your egg-box.
You need:
type = new ArrayList<>();
type.add(t);
for example; or shorter using that little helper method:
type = Arrays.asList(t);
And your other code with items is working because general.type.get(i) returns a single String object; and that is exactly what your Item constructor expects - a single string object.
You are trying to initialize an ArrayList as String. If you tell what you really want to achieve, I can edit the code to do so.
Item Class
public class Item {
public static ArrayList<String> type_list = new ArrayList<>();
public static ArrayList<String> name_list = new ArrayList<>();
public static ArrayList<Double> price_list = new ArrayList<>();
public static ArrayList<Integer> qty_list = new ArrayList<>();
public String type;
public String name;
public Double price;
public Integer qty;
public Item (String type, String name, Double price, Integer qty){
this.type = type;
this.name = name;
this.price = price;
this.qty = qty;
}
}
Main Class
public static void main(String args[]){
ArrayList items_list = new ArrayList<>();
Item.type_list.add("type1");
Item.type_list.add("type2");
Item.type_list.add("type3");
Item.type_list.add("type4");
Item.name_list.add("name1");
Item.name_list.add("name2");
Item.name_list.add("name3");
Item.name_list.add("name4");
Item.price_list.add(price1);
Item.price_list.add(price2);
Item.price_list.add(price3);
Item.price_list.add(price4);
Item.qty_list.add(qty1);
Item.qty_list.add(qty2);
Item.qty_list.add(qty3);
Item.qty_list.add(qty4);
for(int i = 0; i < Item.type_list.size(); i++) {
System.out.println(.....);
}
}
Related
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);
Since JAVA is a strict type language, Ideally a variable of Integer type can only store or refer to Integer type only. But, In this case a variable of Type List is assigned List, how is it possible?
import java.util.*;
public class Main
{
public static void main(String[] args) {
//Defining 2 Lists
List<Long> longList = new ArrayList<>();
List<String> stringList = new ArrayList<>();
//Initialising list of string
stringList.add("1");
stringList.add("abc");
stringList.add("2");
//Initialising variable of object type with list of stirng
Object abcList = stringList;
//Casting Object which is List of String to List Of Long
longList = (List<Long>) abcList;
//Checking values in List of Long
if(longList.contains("abc")){ //TRUE
System.out.println("Yes String exist in String Of Long - \n");
}
if(longList.contains(1L)){ //FALSE
System.out.println("Long exist in List Of Long - \n");
}
}
}
This program is giving output as "Yes String exists in String Of Long". Why is it behaving so? I can't find a reasonable explaination.
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));
}
}
i have a List of an Object, with the following characteristics:
Class Object{
String gender;
String state;
int quantity;
int Salary;
}
List<Object> myList=new ArrayList<Object>;
As input of the List, i have the following:
and as Output, i want to keep only one occurrence of the object with the same gender and the same state, in the same time sum the quantity and the salsary correspanding, like the following:
my question is how can i loop through myList, find objects with the same gender and the same state,keep only one occurence of them, and sum the quantity and the salary correspanding ??
First off, I renamed your class to MyObject as Object is the base Java class. Now for the rest of it - You can use a pseudo-index made out of the gender and state combinations you have already found and sum up the values for the rest of the list as follows:
Class MyObject{
String gender;
String state;
int quantity;
int Salary;
}
List<MyObject> myList=new ArrayList<MyObject>();
List<String> stateAndGender = new ArrayList<String>();
List<MyObject> finalList = new ArrayList<MyObject>();
// add objects here
for(MyObject mO : myList){
String s = mO.getGender();
s+="," + mO.getState();
if(stateAndGender.indexOf(s)==-1)
{
MyObject fO = new MyObject();
fO.setGender(mO.getGender());
fO.setState(mO.getState());
stateAndGender.add(s);
int Qua = mO.getQuantity();
int Sal = mO.getSalary();
for(int i=0; i<myList.size(); i++)
{
if(String t = myList.get(i).getGender()+","+myList.get(i).getGender() == s)
Qua += myList.get(i).getQuantity();
Sal += myList.get(i).getSalary();
}
fO.setQuantity(Qua);
fO.setSalary(Sal);
finalList.add(fO);
}
}
// Then return finalList
The above code assumes you have proper getters for the fields of the class you have created and your gender and state do not contain commas, otherwise you will need to tweak the code.
UPDATE: Now you get a list of the MyObject type with the proper values as you requested! It is not the original one, though, but the one called finalList.
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);
}