group (gather) items of an object - java

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.

Related

Creating objects dynamically using a list of Strings?

I am trying to create objects by using a list of Strings that will populate their fields. For example I have the list of strings, Note that the values repeat after every 3. i.e. id, name , address.
List<String> myList = "Id1", "name1", "address1", "Id2", "name2", "address2";
I would like to dynamically create a number of Person Objects (shown below) using this list
Person object:
public class Person {
private String id;
private String name;
private String address;
public Person() {
}
public Person(String id, String name, String address) {
this.id = id;
this.name = name;
this.address = address;
}
//standard getters and setters
}
What I want to do is have a method that will take the list of strings as an input and then create the objects dynamically. How could I best do this?
I know that I could do the following if I knew that I was definitely populating 2 objects, but the problem is that there may be more or less.
public List<Person> createObjectsFromStringList(List<String> list){
List<person> personList = new Arraylist<>();
Person person1 = new Person(list.get(0), list.get(1), list.get(2));
Person person2 = new Person(list.get(3), list.get(4), list.get(5));
personList.add(person1);
personList.add(person2);
return personList;
}
A simple for loop can do the work:
public List<Person> createObjectsFromStringList(List<String> list) {
List<person> personList = new Arraylist<>();
//We use < size-2 here because we access 2 indeces ahead of x in this loop
for(int x=0; x<list.size()-2; x+=3) {
personList.add(new Person(list.get(x), list.get(x+1), list.get(x+2));
}
return personList;
}
At first glance, I feel like having the different field values across one List is a sign of a poor code structure, but maybe you're already stuck with this List as-is.
Edit:
Now let's suppose you want a partial Person based on the number of remaining elements. Supposing they are still in the same order, you could modify this method to check the validity of the current index for each field:
public List<Person> createObjectsFromStringList(List<String> list) {
List<person> personList = new Arraylist<>();
int size = list.size();
//Now we remove the "-2" from size check because we will handle this ourselves
for(int x=0; x<size; x+=3) {
String id = list.get(x); //Obviously valid
String name = x+1 < size? list.get(x+1) : null;
String address = x+2 < size? list.get(x+2) : null;
personList.add(new Person(id, name, address);
}
return personList;
}
We're using the ternary operation ? ... : null here, so if we run out of elements we set the associated Person field to null instead of using an out-of-bounds index.
You can use recursion
public List<Person> createObjectsFromStringList(List<String> list){
List<person> personList = new Arraylist<>();
for(int i=0; i<list.size(); i++){
personList.add(new Person(list(i),list(i+1),list(i+2)));
i+=2;
}
return personList;
}
Notice that restructuring your list would me much better. make it like this:
List<String> myList = "Id1_name1_address1", "Id2_name2_address2";
Or even use different lists (it is much better). If you change your list structure as above then change the code to this :
public List<Person> createObjectsFromStringList(List<String> list){
List<person> personList = new Arraylist<>();
for(int i=0; i<list.size(); i++){
String[] info= list(i).split("_"); // this will give u a 3element array of yout info IdX nameX addressX
personList.add(new Person(info(0),info(1),info(2)));
}
return personList;
As you want to access your elements sequentially you should use java.util.LinkedList in such loop
for(true)
if(linkedList.size()>=3){
Person person= new
Person(linkedList.removeFirst(),linkedList.removeFirst(),linkedList.removeFirst());
personList.add(person);
}
else break;
But ArrayList and its get method is good for random access by index which is not your case
If you use java 8 you can try something like this:
public List<Person> createObjectsFromStringList(List<String> list) {
//partition by 3 and list.size.
Map<Integer,List<Integer>> map = IntStream
.range(0,list.size())
.boxed()
.collect(Collectors.groupingBy(e->(e)/3));
List<Person> personList = new ArrayList<>();
map.entrySet().forEach(e->{
List<String> per= e.getValue();
Person p = new Person(per.get(0),per.get(1),per.get(2));
personList.add(p);
});
return personList;
}

Java Cannot initialize ArrayList variables in constructor

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

How to find an element in an ArrayList by using a field value of that element?

I am writing a program in Java which accepts user-inputted String in one class.
On a separate class, I have an array-list of class type 'Item' which contains elements of type String (itemName), int, and double. I was wondering if there was a way to either convert the user-inputted String to an object of type 'Item' (I've heard it's difficult), or if there was a way to access the individual String element itemName of the array-list to compare it to the user-inputted String.
Item.java
public class Item {
private String name;
private int monetaryValue;
private double weight;
// Getters and Setters
// ...
// Other methods
// ...
}
I would not use Reflection here: it's using a bazooka for killing a mosquito. I'd rather use plain Java.
Check this example below:
List<Item> myList = new ArrayList<Item>();
String userInputValue;
// * Add some items to myList
// ...
// * Get user input value
// ...
// * Access the array list
int len=myList.size();
for(int i=0; i<len; i++) {
if (myList.get(i).getItemName().equals(userInputValue)) {
// Do something ...
}
}
To create an Item from user input, you can do:
String input1;
String input2;
String input3;
// Assign user input to input1, input2, input3
String itemName = input1;
int data2 = Integer.parseInt(input2);
double data3 = Double.parseDouble(input3);
Item myItem = new Item(itemName, data2, data3);
To access elements from array list, you can do:
List<Item> items;
String input;
// Populate items
// Assignment user input to "input" variable.
for (Item item : items) {
if (item.getItemName().equals(input)) {
// Do something...
}
}
You can of course build Item objects from user input if you define an input format like [name:string] [i:int] [d:double] (example : john 5 3.4). You then just have to split this String and use Integer.parseInt and Double.parseDouble to parse the two last arguments.

How do I use multidimensional arrays with array list?

I want to add some records from sql query but the output is not correct. Always return the last record.
The correct list is :
John
Nick
Mary
Joe
,but always return Joe.
This is the method to add the elements:
public ArrayList<String[][]> getFiledArrayList()
{
// ArrayList<String[][]> fieldsList = new ArrayList<>();
String[][] tempRow = new String[1][2];
ResultSet result;
String sql = "select id, name_of from field";
result = database.exeQueryStatement(sql);
try
{
while(result.next())
{
tempRow[0][0] = result.getString("id");
// System.out.println(tempRow[0][0]);
tempRow[0][1] = result.getString("name_of");
// System.out.println(tempRow[0][1]);
fieldsList.add(tempRow);
System.out.println(fieldsList.get(0)[0][1]);
}
}
catch (SQLException ex)
{
Logger.getLogger(FieldManage.class.getName()).log(Level.SEVERE, null, ex);
}
return fieldsList;
I put the id and the name_of in a String[1][2] table and I want to show the name_of in a jComboBox. Ι want to make an insert and watch the name_of with id
FieldManage fieldmanage = new FieldManage();
ArrayList<String[][]> listOfField;
listOfField = fieldmanage.getFiledArrayList();
String[] fields = new String[listOfField.size()];
System.out.println(listOfField.get(0)[0][0]);
for (int i=0; i<listOfField.size(); i++)
{
fields[i] = listOfField.get(i)[0][1];
System.out.println(fields[i]);//test print show always joe!
}
jComboFields.setModel(new javax.swing.DefaultComboBoxModel(fields));
This code always return Joe.
Also I want to know if there is better way to match an jcombo element with an id.
When populating fieldsList, you repeatedly add references to the same object (tempRow). When your loop modifies the contents of tempRow, all previously added entries also change (since they're the same object).
Move the following line inside the loop:
String[][] tempRow = new String[1][2];
You are trying to create an array of object values.
Using ArrayList<String[][]> is not the way to do this.
Create a class
public class Person {
private long id;
private String name;
public long getId() {
return id;
}
public void setId(long id) {
self.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
self.name = name;
}
}
Then in your code....
ArrayList<Person> myPeople = new ArrayList<Person>();
Person p = new Person();
p.setName("mary");
p.setId(1);
myPeople.add(p);
Start from there, your doing it the hard way, and given that you are having problems understanding arrays and object references, learn the language before you start using multidimensional primitive arrays in conjunction with loops and collections.
Move this line:
String[][] tempRow = new String[1][2];
as the first line in your while(result.next()) loop.
What is happening:
if you put tempRow outside loop, in 2nd iterator on loop same array is modified i.e overwritten by next value. At the completion of while loop, your fieldsList contains the last element only at all indexes.
Run your loop 3 times and you'' see Mary as output.

Order objects in toString based on objects parameter value

I have this toString method set up
public String toString (){
String result;
result = "Ideal Family";
result += "\n"+person1.toString();
result += "\n"+person2.toString();
result += "\n"+person3.toString();
result += "\n"+person4.toString();
result += "\n"+pet1.toString();
result += "\n"+car1.toString();
result += "\n"+car2.toString();
result += "\n"+homeAddress.toString();
return result;
}
in which I list objects in the order I wish to output them. Is there a way to re-order the list based on values within the objects.
Specefically in the Person Class, to re-order the person objects based on an instance variable, an int.
The Person class takes these parameters
public Person (String personName,String personGender,String personSS,int personAge){
name = personName;
ss = personSS;
age = personAge;
gender = personGender;
}
First of all, you should be using a collection instead of having four variables. It would have been easier.
But for what you are looking for, create a list of Persons
List<Person> personList = Arrays.asList(person1, person2, person3, person4);
sort the list
Collections.sort(personList, Comparator<Person>() {
public int compare(Person p1, Person p2) {
return Integer.valueOf(p1.getAge()).compareTo(p2.getAge());
}
});
and iterate through the list
for(Person person : personList) {
result += "\n"+person.toString();
}
Yes, but you need a List or array first.
List<Person> family;
Or:
Person[] family;
Then you can use Collection.sort or Arrays.sort to re-order the family for printing.

Categories