Solved

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

Posted on 2013-06-26
8
180 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
8 Comments
 
LVL 7

Expert Comment

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

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
SharePoint Admin?

Enable Your Employees To Focus On The Core With Intuitive Onscreen Guidance That is With You At The Moment of Need.

 
LVL 36

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
 

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 36

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

Optimize your web performance

What's in the eBook?
- Full list of reasons for poor performance
- Ultimate measures to speed things up
- Primary web monitoring types
- KPIs you should be monitoring in order to increase your ROI

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:
This video teaches viewers about errors in exception handling.
Suggested Courses

627 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