Solved

A better method to eliminate having to create many lists to pare down to the required items.

Posted on 2013-06-26
8
171 Views
Last Modified: 2013-07-22
I am a beginner.
I am being passed a list of values into a method.
Out of the List of value I have to perform evaluarion on the items in the
list with these types 'CISCO', 'IP', 'SRV'.  The List will contain other types but these are the ones that require evaluation.  
If type CISCO has a defict in cost
and there is a surplus for type IP with the same serial as CISCO , set CISCO excess to IP surplus. if type IP has a deficit in cost and type SRV with the same serial as IP has surplus set IP excess to SRV surplus

The items in the list are:   name  type  serial cost  laborcost  excess

The only way that I know how to do this is to create 6 lists .  Is there a better way to do this?
 
What I'm current doing is
 looping through the passed list
  if type = 'CISCO' and cost < laborCost
      ADD TO deficitCISCOList
 if type = 'IP' and cost < laborCost
     ADD TO deficitIPList

Create the surplus list
   if type = 'IP' and cost > laborCost
      add to excessIPList
  if type = 'SRV' and cost > laborCost
      add to excessSRVList

loop through
    deficitCISCOList
      loop through excessIPList
         if IPCost serial = CISCO serial
            update  deficitCISCOList excess with  excessIPList laborCost
            add to adjustCISCOList

loop through
 deficitIPList
    loop through excessSRVList
         if IPCost serial = SRV serial
            update  deficitIPList excess with  excessSRVList
                                                   laborCost
            add to adjustIPList

After that, I loop through the adjustCISCOList and the list passed to the method  until I find the matching type and serial and update the passed list excess.
0
Comment
Question by:cookiejar
  • 4
  • 3
8 Comments
 
LVL 7

Expert Comment

by:gudii9
ID: 39280181
How are items in the list  are related?
0
 
LVL 35

Expert Comment

by:mccarl
ID: 39280267
Can you write a compilable, self-contained example of this so that we have something to work with? Something along the lines of...
public class ItemProcessingExample {
  public static void main(String[] args) {
    List<Item> items = new ArrayList<Item>();
    items.add(new Item("My Name", "CISCO", "1234AB765S", 0.5, 0.8, 1.2));
    // continue the above to add all the example items

    processItemsList(items);

    System.out.println(items);
  }

  private static void processItemsList(List<Item> items) {
    // This is where we will implement your logic
  }

  private static class Item {
    public String name;
    public String type;
    // etc, etc for each field

    public Item(String name, String type /* etc, etc for each field to be initialised*/) {
      this.name = name;
      this.type = type;
      // etc, etc
    }
  }
}

Open in new window

Now if you flesh the above out, with extra example items that show the conditions that you expect and have the right values that will exercise your above logic, AND give us what the expected output should be, ie. list all items that should be there AFTER the method is run AND all the field values for each item. Then we have something to work with where we can provide code to go inside that method and show you some ways to avoid using so many lists.

Check out this site: http://sscce.org/ for a guide on good ways to pose coding problems.
0
 

Author Comment

by:cookiejar
ID: 39282207
I have attached the sample code.

The question is how can I optimize the attached code.  I think I a looping through too many lists.
SAMPLE.txt
0
 
LVL 35

Accepted Solution

by:
mccarl earned 500 total points
ID: 39283517
I did ask that the sample was compilable, but anyway... I fixed it so that it does compile, but there may be a small chance that I changed your logic in the process. This shouldn't matter to this discussion though.

In the code below I have added a method that does the processing how I would do it. You will more than likely have to change the actual processing down in the flowDown method, but again that is not exactly what this question is about. (Note that this was hard because your code contradicts it self, and the description that you provided above, so I will leave that part up to you)

However, the main point about this code is how two find pairs of items in the list and then perform some processing. So here is a brief description of what it is doing... It finds the first item (and stores that in the map of previous items for later) It is a CISCO with serial 201, and it hasn't previously seen any IP item with serial 201, so it does nothing. The next item is an IP item with serial 201, now it looks in the map and finds a CISCO with serial 201, so it can now do its processing. It has a reference to both items, so it can retrieve whatever fields it needs and it can also set new values for whatever fields. When you look at the code, there are two "if" blocks for each CISCO<->IP and IP<->SRV. That is because those items could appear if either order, ie. CISCO then IP, or IP then CISCO, so it handles both cases.

Also, note that the above processing is based on the assumption that there will only ever be 1 item for a Type/Serial combination, ie. you CAN'T have "ItemA, CISCO, 201" and "ItemB, CISCO, 201". If that is the case, then my method won't work, but I doubt that is the case.

The important lines are between 44 and 93.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ItemProcessingExample {
    public static void main(String[] args) {
        List<Item> items = Arrays.asList(new Item[] { 
                new Item("ItemA", "CISCO", "201", 50, 100, 0), 
                new Item("ItemB", "IP", "201", 200, 20, 0), 
                new Item("ItemC", "SRV", "100", 800, 200, 0), 
                new Item("ItemD", "IP", "100", 400, 600, 0), 
                new Item("ItemE", "IP", "111", 100, 50, 0), 
                new Item("ItemG", "AVA", "111", 100, 50, 0),
        
        });
        System.out.println(items);
        processitemsList(items);
        System.out.println(items);
        
        System.out.println();
        
        
        
        // Test using mccarl's method
        List<Item> itemsCopy = Arrays.asList(new Item[] { 
                new Item("ItemA", "CISCO", "201", 50, 100, 0), 
                new Item("ItemB", "IP", "201", 200, 20, 0), 
                new Item("ItemC", "SRV", "100", 800, 200, 0), 
                new Item("ItemD", "IP", "100", 400, 600, 0), 
                new Item("ItemE", "IP", "111", 100, 50, 0), 
                new Item("ItemG", "AVA", "111", 100, 50, 0),
        
        });
        System.out.println(itemsCopy);
        processitemsList_MCCARLS_method(itemsCopy);
        System.out.println(itemsCopy);
    }
    
    
    // VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
    
    private static void processitemsList_MCCARLS_method(List<Item> items) {
        Map<String, Item> previousItems = new HashMap<String, Item>();
        
        for (Item item : items) {
            previousItems.put(item.getType() + item.getSerial(), item);
            
            
            // Process CISCO - IP items
            if ("CISCO".equals(item.getType())) {
                Item ipItem = previousItems.get("IP" + item.getSerial());
                if (ipItem != null) {
                    // item (which is a CISCO) and ipItem (which is an IP) have the same serial number, so we can just do your required processing
                    flowDown(ipItem, item);
                }
            }
            if ("IP".equals(item.getType())) {
                Item ciscoItem = previousItems.get("CISCO" + item.getSerial());
                if (ciscoItem != null) {
                    // item (which is a IP) and ciscoItem (which is an CISCO) have the same serial number, so we can just do your required processing
                    flowDown(item, ciscoItem);
                }
            }
            
            
            // Process SRV - IP items
            if ("SRV".equals(item.getType())) {
                Item ipItem = previousItems.get("IP" + item.getSerial());
                if (ipItem != null) {
                    // item (which is a SRV) and ipItem (which is an IP) have the same serial number, so we can just do your required processing
                    flowDown(item, ipItem);
                }
            }
            if ("IP".equals(item.getType())) {
                Item srvItem = previousItems.get("SRV" + item.getSerial());
                if (srvItem != null) {
                    // item (which is a IP) and srvItem (which is an SRV) have the same serial number, so we can just do your required processing
                    flowDown(srvItem, item);
                }
            }
        }
    }

    private static void flowDown(Item flowDownFromItem, Item flowDownToItem) {
        if (flowDownToItem.getCost() < flowDownToItem.getLaborCost() && 
                flowDownFromItem.getCost() > flowDownFromItem.getLaborCost()) {
            double deficitVariance = flowDownToItem.getCost() - flowDownToItem.getLaborCost();
            flowDownToItem.setExcess(deficitVariance);
            flowDownFromItem.setCost(flowDownFromItem.getCost() - deficitVariance);
        }
    }
    
    
    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    private static void processitemsList(List<Item> items) {
    // This is where we will implement your logic

        List<Item> ciscoList = new ArrayList<Item>();
        List<Item> ipList = new ArrayList<Item>();
        List<Item> srvList = new ArrayList<Item>();

        // Load ciscos, ips and srvs into 3 separate lists
        for (Item vo : items) // these are from fake array right now
        {

            if (0 == vo.getType().compareTo("IP"))
            {
                ipList.add(vo);
            }

            if (0 == vo.getType().compareTo("CISCO"))
            {
                ciscoList.add(vo);
            }

            if (0 == vo.getType().compareTo("SRV"))
            {
                srvList.add(vo);
            }

        }

        // Get ciscos and ips with deficits
        List<Item> deficitciscoList = new ArrayList<Item>();
        List<Item> deficitipList = new ArrayList<Item>();

        deficitciscoList = getciscosWithDeficit(ciscoList, deficitciscoList);
        deficitipList = getipsWithDeficit(ipList, deficitipList);

        // flow down from ips to ciscos; flow down form ips to srvs
        List<Item> flowdownipList = new ArrayList<Item>();
        List<Item> flowdownsrvList = new ArrayList<Item>();

        flowdownipList = flowdownsipTocisco(deficitciscoList, ipList,
                flowdownipList);
        flowdownsrvList = flowdownssrvToip(deficitipList, srvList,
                flowdownsrvList);

        
        /*  I would like to update Item with  flowdownipList and flowdownsrvList  lists.
       Expected Update List
         
	    Item ("ItemA", "CISCO", "201", 50, 100, 50),
            Item ("ItemB", "IP",    "201", 150, 20, 0),
            Item ("ItemC", "SRV",   "100", 600, 200, 0),
            Item ("ItemD", "IP",    "100", 400, 600, 200),
            Item ("ItemE", "IP",    "111", 100 50, 0),
            Item ("ItemG", "AVA",   "111", 100 50, 0),
        	   
       */

    }
    
    public static List<Item> getciscosWithDeficit(List<Item> ciscoList, List<Item> deficitciscoList) {
        for (Item vo : ciscoList) {
            if (vo.getCost() < vo.getLaborCost()) {
                deficitciscoList.add(vo);
            }
        }
        
        return deficitciscoList;
    }
    
    public static List<Item> getipsWithDeficit(List<Item> ipList, List<Item> deficitipList) {
        for (Item vo : ipList) {
            if (vo.getCost() < vo.getLaborCost()) {
                deficitipList.add(vo);
            }
        }
        
        return deficitipList;
    }
    
    public static List<Item> flowdownsipTocisco(List<Item> deficitciscoList, List<Item> ipList, List<Item> flowdownipList) {
        double deficitVariance = 0;
        int flowdownQty = 0;
        
        for (Item ciscovo : deficitciscoList) {
            for (Item ipvo : ipList) {
                if (ciscovo.getSerial()
                        .equals(ipvo.getSerial()) && ipvo.getCost() > ipvo.getLaborCost()) {
                    deficitVariance = ciscovo.getCost() - ciscovo.getLaborCost();
                    
                    // Set to the amount of excess needed
                    ciscovo.setExcess(deficitVariance);
                    
                    // Subtract the amount that is flowed down to cisco from ip
                    // Cost.
                    ipvo.setCost(ipvo.getCost() - deficitVariance);
                    
                    // Add the updated ciscos and ips to the list.
                    flowdownipList.add(ciscovo);
                    flowdownipList.add(ipvo);
                    break;
                }
            }
        }
        return flowdownipList;
    }
    
    public static List<Item> flowdownssrvToip(List<Item> deficitipList, List<Item> srvList, List<Item> flowdownsrvList) {
        double deficitVariance = 0;
        int flowdownQty = 0;
        
        for (Item ipvo : deficitipList) {
            for (Item srvvo : srvList) {
                if (ipvo.getSerial()
                        .equals(srvvo.getSerial()) && srvvo.getCost() > srvvo.getLaborCost()) {
                    deficitVariance = ipvo.getCost() - ipvo.getLaborCost();
                    
                    // Set to the amount of excess needed
                    ipvo.setExcess(deficitVariance);
                    
                    // Subtract the amount that is flowed down to ip from srv
                    // Cost.
                    srvvo.setCost(ipvo.getCost() - deficitVariance);
                    
                    // Add the updated ciscos and ips to the list.
                    flowdownsrvList.add(ipvo);
                    flowdownsrvList.add(srvvo);
                    break;
                }
            }
        }
        return flowdownsrvList;
    }
    
    private static class Item {
        public String name;
        public String type;
        public String serial;
        public double cost;
        public double laborCost;
        public double excess;
        
        public Item(String name, String type, String serial, double cost, double laborCost, double excess) {
            this.name = name;
            this.type = type;
            this.serial = serial;
            this.cost = cost;
            this.laborCost = laborCost;
            this.excess = excess;
        }

        public String getName() {
            return name;
        }

        public String getType() {
            return type;
        }

        public String getSerial() {
            return serial;
        }

        public double getCost() {
            return cost;
        }

        public void setCost(double cost) {
            this.cost = cost;
        }

        public double getLaborCost() {
            return laborCost;
        }

        public double getExcess() {
            return excess;
        }

        public void setExcess(double excess) {
            this.excess = excess;
        }

        @Override
        public String toString() {
            return "Item [name=" + name + ", type=" + type + ", serial=" + serial + ", cost=" + cost + ", laborCost=" + laborCost + ", excess=" + excess + "]";
        }
    }
}

Open in new window

0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:cookiejar
ID: 39285289
What does previousItems.get("IP" + item.getSerial()) do?
0
 

Author Comment

by:cookiejar
ID: 39285388
Does  previousItems.get("IP" + item.getSerial())  guarantee that this will get the same sertial as the CISCO.
0
 

Author Comment

by:cookiejar
ID: 39285463
If the first item is not always cisco will this work?
0
 
LVL 35

Expert Comment

by:mccarl
ID: 39285944
What does previousItems.get("IP" + item.getSerial()) do?
It finds the previously seen IP item with the same serial as the current item (CISCO or SRV depending on if you are talking about line 53 or line 70). It may or may not be there, depending on the order of the items, so that call will either return the object or return null. So yes, it guarantees that it will only bring back an item with the SAME serial.

If the first item is not always cisco will this work?
Yes, it will still work. That is what I was trying to highlight in the last part of my previous post. If the first item is an IP and then later there is a CISCO (with the same serial) then the "if" block at lines 52-58 will pick that up. But if the CISCO is first followed by the IP, as in your example, then the "if" block at lines 59-65 is what will find that.
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Suggested Solutions

For customizing the look of your lightweight component and making it look lucid like it was made of glass. Or: how to make your component more Apple-ish ;) This tip assumes your component to be of rectangular shape and completely opaque. (COD…
Java Flight Recorder and Java Mission Control together create a complete tool chain to continuously collect low level and detailed runtime information enabling after-the-fact incident analysis. Java Flight Recorder is a profiling and event collectio…
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now