Iteration over nested arraylist structure shows unexpected results - java

I have a nested arraylist structure over which I need to iterate. See the following:
ArrayList<ArrayList<SubjectnameandMark>> level2arraylist = new ArrayList<ArrayList<SubjectnameandMark>>();
Then I have the following arraylists that I would add to the level2arraylist
ArrayList<SubjectnameandMark> st1 = new ArrayList<SubjectnameandMark>();
ArrayList<SubjectnameandMark> st2 = new ArrayList<SubjectnameandMark>();
ArrayList<SubjectnameandMark> st3 =new ArrayList<SubjectnameandMark>();
My SubjectnameandMark class is given below:
public class SubjectnameandMark
{
String name;
double mark;
SubjectnameandMark(String name, double mark)
{
this.name=name;
this.mark=mark;
}
}
I am adding the subject names and marks to each student(st1, st2...) arraylist in the following way:
SubjectnameandMark sub1 = new ServtermnameandWeight("math",1.0);
SubjectnameandMark sub2 = new ServtermnameandWeight("geo",1.0);
SubjectnameandMark sub3 = new ServtermnameandWeight("physics",0.389);
st1.add(sub1);
st1.add(sub2);
st1.add(sub3);
............
Note that this process is repeated for all st that is st1, st2, st3....
Finally I am adding all st arraylists to level2arraylist with the following:
level2arraylist.add(st1);
level2arraylist.add(st2);
level2arraylist.add(st3);
....................
Now I am trying to iterate over these nested arraylist to see the subject name and marks:
for (l=0;l<level2arraylist.size();l++)
{
for(n=0;n<level2arraylist.get(l).size();n++)
{
studenttomatch= level2arraylist.get(l);
Iterator<SubjectnameandMark> itr=studenttomatch.iterator();
while(itr.hasNext())
{
SubjectnameandMark st=(SubjectnameandMark)itr.next(); System.out.println(st.servterm+" "+st.servtermweight);
}
}
}
The problem is that not all subject and marks are shown. However, If I restrict the loop variable in the following way the specific record at that particular index is shown, for example I am only restricting to the first record (l=0;l<1) and the correct results are shown:
for (l=0;l<1;l++)
{
for(n=0;n<level2arraylist.get(l).size();n++)
{
studenttomatch= level2arraylist.get(l);
Iterator<SubjectnameandMark> itr=studenttomatch.iterator();
while(itr.hasNext())
{
SubjectnameandMark st=(SubjectnameandMark)itr.next();
System.out.println(st.servterm+" "+st.servtermweight);
}
}
}

There's no need for the double for-loop structure here since you're using an iterator. If you're iterating through all the elements in level2arraylist, then you don't need a for loop to iterate through all the elements in level2arraylist.get(l) because that's essentially what your iterator is doing. So simply just remove the inner for loop like so,
for (l=0;l<level2arraylist.size();l++)
{
studenttomatch= level2arraylist.get(l);
Iterator<SubjectnameandMark> itr=studenttomatch.iterator();
while(itr.hasNext())
{
SubjectnameandMark st=(SubjectnameandMark)itr.next();
System.out.println(st.servterm+" "+st.servtermweight);
}
}

Related

Add a list into a BinarySearchTree <Integer, List<Object>>

I'm new in Java and I want to add a list into a BinarySearchTree with an Integer as a Key and a List as value.
So I need every element of a list that I want to add and add to the BST.
I'm using BST because I need to sort it with the key.
In the class Group I have a method called getNumber() that return the number os elements in the that group and the key will be the number of elements of a Group.
Right now I have this and I don't know how to continue. groups.iterator() is just to iterate every group of a list.
orderedGroups is a BinarySearchTree <Integer, List<Group>>().
EDIT:
I have this.
public Iterator<Entry<Integer, List<Group>>> listWarriors() throws NoGroupsException {
if(!isThereGroup())
throw new NoGroupsException();
Iterator<Entry<String, Group>> it = groups.iterator();
List<Group> listGroup = new DoublyLinkedList<Group>();
int j = 0;
while(it.hasNext()) {
listGroup.add(j, it.next().getValue());
j++;
}
for(int i = 0; i<j; i++) {
List<Group> list = orderedGroups.find(listGroup.get(i).getNumber());
if(list == null) {
list = new DoublyLinkedList<Group>();
list.addFirst(listGroup.get(i));
orderedGroups.insert(-(listGroup.get(i).getNumber()), list);
}
else {
if(list.equals(listGroup.get(i))) {
list.addFirst(listGroup.get(i));
}
}
}
return orderedGroups.iterator();
}
OrderedDictionary > orderedGroups = new BinarySearchTree>();
And a group is added by doing this.
public void addGroup(String idGrupo, String nome) throws GroupAlreadyExistsException {
if(searchGroup(idGrupo))
throw new GroupAlreadyExistsException();
group = new GroupClass(idGrupo, nome);
groups.insert(idGrupo.toLowerCase(), group);
}
I have all these in a Class called System.
It looks like you think you have to roll your own iterator in order to enumerate your list. Not necessary.
I can't tell exactly what you are trying to do here, but maybe the below will help, which just demonstrates how to iterate a list.
void addListToGroup(List<Foo> myList, List<group> myGroups) {
for (Foo foo : myList) {
Object value=myList.someFunction();
Group newGroup = new Group(value);
myGroups.add(newGroup);
}
}
I'm not sure I understand fully what you're trying to do, and why you're not using LinkedList and TreeMap, but I see a few issues in your code:
your for loop makes i start at 1 whereas list indices start at 0,
building listGroup seems useless: you could directly build orderedGroups
orderedGroups is not modified in your code (orderedGroupsByC is though)
UPDATE:
What if you did this:
Iterator<Entry<String, Group>> it = groups.iterator();
while (it.hasNext()) {
Group group = it.next();
List<Group> list = orderedGroups.find(group.getNumber());
if (list == null) {
list = new DoublyLinkedList<Group>();
list.addFirst(group);
orderedGroups.insert(group.getNumber(), list);
} else {
list.addFirst(group);
}
}

Displaying group of elements in an Arraylist

i'm trying to display few elements of an arraylist if contition is true. The method gets String that should be found in arrayList. After that there are some other values that are contained after the line in List that has beed found.
I need to print thause line's out that would be 1_4_1334-Automatic.... I have tried to use Iterator but with no luck. It just seens that i just cannot get it.
So if am looking for 2210002_4_1294-Group i should get all strings that contain "Automatic" till 2210003_4_1295-Group is reached.
Any idea how it could be done ?
Thanks a lot :)
MyArrayList:
2210002_4_1294-Group
1_4_1334-Automatic
2_4_1336-Automatic
3_4_1338-Automatic
4_4_1340-Automatic
5_4_1342-Automatic
6_4_1344-Automatic
7_4_1346-Automatic
8_4_1348-Automatic
9_4_1350-Automatic
2210003_4_1295-Group
1_4_1378-Automatic
2_4_1380-Automatic
2210004_4_1296-Group
1_4_1384-Manual
2_4_1386-Manual
Method might look like this:
private void findValueInList(String group){
Iterator<String> iter = arrayList.iterator();
while(iter.hasNext()){
String name = iter.next();
if(name.equals(group)){
here i need to get ValueThatINeed
}
}
}
I guess your question is already answered Here
Simply iterate over your arraylist and check each value like the code below:
ArrayList<String> myList ...
String searchString = "someValue";
for (String curVal : myList){
if (curVal.contains(searchString)){
// The condition you are looking for is satisfied
}
}
I solved it like this:
private ArrayList<String> filterList(String nameToFind) {
ArrayList<String> elements = new ArrayList<String>();
for (int i = 0; i < list.size(); i++) {
if (list.get(i).equals(nameToFind)) {
while (list.get(i+1).contains("Manual") || list.get(i+1).contains("Automatic")) {
elements.add(list.get(i+1));
i++;
}
}
}
return elements;
}

Removing the contents of an arraylist of customized object type based on a specific comparison between the elements of the arraylist

I have an ArrayList of type RemoveTest, where RemoveTest is a user defined class.
RemoveTest has two properties of String type mId and rmId.
I need to find in the ArrayList, elements(Objects of type RemoveTest) satisfying the below criteria: such that the value of obj1.rmId() is same as obj2.getmId() and then remove both of these elements(obj1 and obj2).
I tried this by writing the below code:
import java.util.ArrayList;
import java.util.Iterator;
public class RemoveItr {
public static void main(String[] args){
ArrayList<RemoveTest> eleList = new ArrayList<RemoveTest>();
RemoveTest obj1 = new RemoveTest();
obj1.setmId("m1");
obj1.setRmId("");
RemoveTest obj2 = new RemoveTest();
obj2.setmId("m2");
obj2.setRmId("m1");
RemoveTest obj3 = new RemoveTest();
obj3.setmId("m3");
obj3.setRmId("");
RemoveTest obj4 = new RemoveTest();
obj4.setmId("m4");
obj4.setRmId("m3");
RemoveTest obj5 = new RemoveTest();
obj5.setmId("m5");
obj5.setRmId("");
eleList.add(obj1);
eleList.add(obj2);
eleList.add(obj3);
eleList.add(obj4);
eleList.add(obj5);
Iterator<RemoveTest> i = eleList.iterator();
while(i.hasNext()){
RemoveTest fwdM =(RemoveTest)i.next();
String fwdId = fwdM.getmId();
Iterator<RemoveTest> ni = eleList.iterator();
while(ni.hasNext()){
RemoveTest revM =(RemoveTest)ni.next();
String revId = revM.getRmId();
if(fwdId.equals(revId)){
System.out.println("fwdId "+fwdId+"- revId "+revId);
i.remove();
ni.remove();
}
}
}
}
}
public class RemoveTest {
String mId;
String rmId;
public String getmId() {
return mId;
}
public void setmId(String mId) {
this.mId = mId;
}
public String getRmId() {
return rmId;
}
public void setRmId(String rmId) {
this.rmId = rmId;
}
}
Note: both classes are Public as they were not in the same source file.
But, I got ConcurrentModificationException and I believe it is because, that as I was already in the middle of iterating through the arraylist, and then other loop(iterator) steps in and tries to operate on the same ArrayList.
Is this understanding correct? and If so, how can I resolve this problem and achieve the solution.
You can't modify a collection while iterating over it, except by using Iterator.remove().
This rule implies that you can't use two iterators simultaneously and expect remove() to work, because calling remove() on one iterator will violate the rule for the other iterator.
The solution is to collect all the entries that need deleting in a separate Set, then after your logic has completed, call List.removeAll(set).
Given this, you don't need iterators at all - just use the foreach syntax:
For a simplistic example:
List<RemoveTest> list = new ArrayList<RemoveTest>();
// populate list
Set<RemoveTest> removals = new HashSet<RemoveTest>();
for (RemoveTest i : list)
for (RemoveTest j : list)
if (...)
removals.add(i); // j will get added in another iteration
list.removeAll(removals);
Use CopyOnWriteArrayList instead of ArrayList, it should solve your problem.

Iterating through an array List and creating new ArrayLists when values are different, is this even possible?

I am fairly new to Java and I have stumbled across a problem I cannot figure out for the life of me. First let me explain what I am trying to do then I will show you the code I have so far.
I have a webservice that returns an array of arrays(which include company and lines of business strings). I wish to transform this into a string list, which I did in the first line of code below. Then I wish to Iterate through the list and every I come across a different value for company, I want to create a new ArrayList and add the associated line of business to the new list. Example output of webservice: 80,80,64,64 (this is presorted so the same companies will always be grouped together) the associated lobs would be 1,2,3,4 respectively. What I want: arraylist[0]: 1,2 arrayList[1]: 3,4
What I have so far:
List coList = Arrays.asList(coArray);
//create list of lists
List<List<String>> listOfLists = new ArrayList<List<String>>();
String cmp = "";
for (int i=0;i<coList.size();i++){//loop over coList and find diff in companies
String currentCo = ((__LOBList)coList.get(i)).getCompany();
String currentLob = ((__LOBList)coList.get(i)).getLobNum();
if(i<coArray.length-1){
String nextCo = ((__LOBList)coList.get(i+1)).getCompany();
if((currentCo.equals(nextCo))){
//do nothing companies are equal
}else{
log("NOT EQUAL"); //insert logic to create a new array??
ArrayList<String> newList = new ArrayList<String>();
// for(int j=0;j<coList.size();j++){
newList.add( ((__LOBList)coList.get(i)).getLobNum());
// }
for(int k=0; k<listOfLists.size();k++){//loop over all lists
for(int l=0;l<listOfLists.get(k).size();l++){ //get first list and loop through
}
listOfLists.add(newList);
}
}
}
}
My problem here is that it is not adding the elements to the new string array. It does correctly loop through coList and I put a log where the companies are not equal so I do know where I need to create a new arrayList but I cannot get it to work for the life of me, please help!
Yes you can do this but it's really annoying to write in Java. Note: This is a brain dead simple in a functional programming language like Clojure or Haskell. It's simply a function called group-by. In java, here's how I'd do this:
Initialize a List of Lists.
Create a last pointer that is a List. This holds the last list you've added to.
Iterate the raw data and populate into the last as long as "nothing's changed". If something has changed, create a new last.
I'll show you how:
package com.sandbox;
import java.util.ArrayList;
import java.util.List;
public class Sandbox {
public static void main(String[] args) {
ArrayList<String> rawInput = new ArrayList<String>();
rawInput.add("80");
rawInput.add("80");
rawInput.add("60");
rawInput.add("60");
new Sandbox().groupBy(rawInput);
}
public void groupBy(List<String> rawInput) {
List<List<String>> output = new ArrayList<>();
List<String> last = null;
for (String field : rawInput) {
if (last == null || !last.get(0).equals(field)) {
last = new ArrayList<String>();
last.add(field);
output.add(last);
} else {
last.add(field);
}
}
for (List<String> strings : output) {
System.out.println(strings);
}
}
}
This outputs:
[80, 80]
[60, 60]
Of course, you can do what the other guys are suggesting but this changes your data type. They're suggesting "the right tool for the job", but they're not mentioning guava's Multimap. This will make your life way easier if you decide to change your data type to a map.
Here's an example of how to use it from this article:
public class MutliMapTest {
public static void main(String... args) {
Multimap<String, String> myMultimap = ArrayListMultimap.create();
// Adding some key/value
myMultimap.put("Fruits", "Bannana");
myMultimap.put("Fruits", "Apple");
myMultimap.put("Fruits", "Pear");
myMultimap.put("Vegetables", "Carrot");
// Getting the size
int size = myMultimap.size();
System.out.println(size); // 4
// Getting values
Collection<string> fruits = myMultimap.get("Fruits");
System.out.println(fruits); // [Bannana, Apple, Pear]
Collection<string> vegetables = myMultimap.get("Vegetables");
System.out.println(vegetables); // [Carrot]
// Iterating over entire Mutlimap
for(String value : myMultimap.values()) {
System.out.println(value);
}
// Removing a single value
myMultimap.remove("Fruits","Pear");
System.out.println(myMultimap.get("Fruits")); // [Bannana, Pear]
// Remove all values for a key
myMultimap.removeAll("Fruits");
System.out.println(myMultimap.get("Fruits")); // [] (Empty Collection!)
}
}
It sounds to me like a better choice would be a Map of Lists. Let the company ID be the key in the Map and append each new item for that company ID to the List that's the value.
Use the right tool for the job. Arrays are too low level.
Create a Map<String, List<Bussiness>>
Each time you retrieve a company name, first check if the key is already in the map. If it is, retrieve the list and add the Bussiness object to it. If it is not, insert the new value when a empty List and insert the value being evaluated.
try to use foreach instead of for
just like
foreach(List firstGroup in listOfLists)
foreach(String s in firstGroup)
............
Thanks for the input everyone!
I ended up going with a list of lists:
import java.util.*;
import search.LOBList;
public class arraySearch {
/**
* #param args
*/
public static void main(String[] args) {
LOBList test = new LOBList();
test.setCompany("80");
test.setLOB("106");
LOBList test1 = new LOBList();
test1.setCompany("80");
test1.setLOB("601");
LOBList test2 = new LOBList();
test2.setCompany("80");
test2.setLOB("602");
LOBList test3 = new LOBList();
test3.setCompany("90");
test3.setLOB("102");
LOBList test4 = new LOBList();
test4.setCompany("90");
test4.setLOB("102");
LOBList test5 = new LOBList();
test5.setCompany("100");
test5.setLOB("102");
LOBList BREAK = new LOBList();
BREAK.setCompany("BREAK");
BREAK.setLOB("BREAK");
BREAK.setcompany_lob("BREAK");
// create arraylist
ArrayList<LOBList> arlst=new ArrayList<LOBList>();
// populate the list
arlst.add(0,test);
arlst.add(1,test1);
arlst.add(2,test2);
arlst.add(3,test3);
arlst.add(4,test4);
arlst.add(5,test5);
//declare variables
int idx = 0;
String nextVal = "";
//loops through list returned from service, inserts 'BREAK' between different groups of companies
for(idx=0;idx<arlst.size();idx++){
String current = arlst.get(idx).getCompany();
if(idx != arlst.size()-1){
String next = arlst.get(idx+1).getCompany();
nextVal = next;
if(!(current.equals(next))){
arlst.add(idx+1,BREAK);
idx++;
}
}
}
//add last break at end of arrayList
arlst.add(arlst.size(),BREAK);
for(int i=0;i<arlst.size();i++){
System.out.println("co:" + arlst.get(i).getCompany());
}
//master array list
ArrayList<ArrayList<LOBList>> mymasterList=new ArrayList<ArrayList<LOBList>>();
mymasterList = searchListCreateNewLists(arlst);
//print log, prints all elements in all arrays
for(int i=0;i<mymasterList.size();i++){
for(int j=0;j<mymasterList.get(i).size();j++){
System.out.println("search method: " + mymasterList.get(i).get(j).getCompany());
}
System.out.println("end of current list");
}
}
//method to loop over company array, finds break, creates new array list for each company group,
//adds this to a list of lists(masterList)
public static ArrayList<ArrayList<LOBList>> searchListCreateNewLists(ArrayList<LOBList> list){
ArrayList<ArrayList<LOBList>> masterList=new ArrayList<ArrayList<LOBList>>();
int end = 0;
int start = 0;
int index = 0;
for(int i=0;i<list.size();i++){
if(list.get(i).getCompany().equals("BREAK")){
end = i;//end is current index
masterList.add(new ArrayList<LOBList>());
for(int j = start;j<end;j++){
masterList.get(index).add(list.get(j));
}
index++;
start = i+1;
}
}
return masterList;
}
}
The output is:
search method: 80
search method: 80
search method: 80
end of current list
search method: 90
search method: 90
end of current list
search method: 100
end of current list
So all company LOBList objects with Company: 80, are grouped together in a list, as are 90 and 100.
To iterate through the list you can use
ListIterator litr = coList.listIterator();
while(litr.hasNext()){
}

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.

Categories