Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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!

share|improve this question
 
Look like this line is your culprit -- newList.add( ((__LOBList)coList.get(i)).getLobNum()); I think it should be newList.add( ((__LOBList)coList.get(i+1)).getLobNum()); //Note that i updated to i+1 –  myqyl4 Jun 11 '13 at 20:21
add comment

6 Answers

up vote 0 down vote accepted

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:

  1. Initialize a List of Lists.
  2. Create a last pointer that is a List. This holds the last list you've added to.
  3. 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!)
 }
}
share|improve this answer
 
Awesome, thanks for the help! I didn't even realize a multimap existed, Here is a question though. If I wanted to keep the data in the type __LOBList (which has several string fields) is there a way to do this with the multimap? I am just thinking down the line that I may need use some of the information that I would be discarding If I used the company as a key and the lines of businesses as values –  Eric Jun 11 '13 at 20:36
 
@Eric Yes, the Multimap.put takes <K,V>. It can be any object you want. –  tieTYT Jun 11 '13 at 20:42
 
@Eric I may have misunderstood. If __LOBList is the list of values (rather than the values), you'd have to implement your own Multimap interface to do that. It's probably easier than it sounds because I'm sure there's an abstract class you can just extend that does 90% of the work for you. Alternatively, you can just add a constructor on __LOBList that takes a list and knows how to convert it. That seems even easier. –  tieTYT Jun 11 '13 at 20:44
 
thanks for the update, sorry if I wasn't clear I had such a long day yesterday and I may have left out key information. Basically __LOBList holds a list of values, and after my webservice runs it returns an array(results) of objects(__LOBList) which has strings that hold the values. I am trying to iterate through the list,(which is dynamic the number and values of the objects might change), and create a new array of __LOBList objects that all have a common value in the field 'company', and then from here I am going to create new htmlSelectManyCheckbox groups(JSF) –  Eric Jun 12 '13 at 14:10
 
So basically whenever the value of 'company' is different it will create a new arrayList and store all the objects with the same company in that list –  Eric Jun 12 '13 at 14:17
show 1 more comment

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.

share|improve this answer
add comment

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.

share|improve this answer
add comment

try to use foreach instead of for

just like

foreach(List firstGroup in listOfLists) foreach(String s in firstGroup) ............

share|improve this answer
add comment

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.

share|improve this answer
add comment

To iterate through the list you can use

  ListIterator litr = coList.listIterator();
  while(litr.hasNext()){



  }
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.