Solved

Summary counts for a two-dimensional array...

Posted on 2003-12-07
31
999 Views
Last Modified: 2010-03-31
I've created an array that is populated by asking a user for values.
Now I'm trying to create summary values based off the populated array(s).
Here is the format of the array:

outputData[j][0] = countryNameString;
outputData[j][1] = currencyNameString;
outputData[j][2] = internationalAmountString;
outputData[j][3] = dollarAmountString;
outputData[j][4] = paymentMethodString;
outputData[j][5] = stdDateFormat2.format(expenseDate);

The summary needs to count only those countries that have been entered in [j][0] and list them in alphabetical order.  The second summary gives a count of the payment method [j][4], and needs to list the payment method whether it is chosen or not.  These are to be listed in descending rank by count.  I have a switch/case that lists all payment methods.

Help.
0
Comment
Question by:BlueTrane
[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
  • 12
  • 10
  • 9
31 Comments
 
LVL 4

Expert Comment

by:vk33
ID: 9894753
Sorry, could you supply some code of yours? Otherwise it looks like hometask which we're prohibited to do...
0
 

Author Comment

by:BlueTrane
ID: 9894811
Sure.  It's quite long but here's the for loop for getting info from the user and populating the array:

for (int i = 1; i<=200; i++)
{
      j = i - 1;
      boolean validDate = false;
      do
      {
            super.setDateMonth(currentMonth);
            super.setDateDay(currentDay);
            super.setDateYear(currentYear);
            GregorianCalendar expenseDateGreg = new GregorianCalendar(super.getDateYear(),
            super.getDateMonth() - 1, super.getDateDay());
            expenseDate = expenseDateGreg.getTime();
            expenseDateString = stdDateFormat.format(expenseDate);

            int start = expenseDateGreg.get(Calendar.DAY_OF_YEAR);
            int end = dateTodayGreg.get(Calendar.DAY_OF_YEAR);
            int daysBetween = end - start;

            if (expenseDateGreg.before(dateTodayGreg))
            {
                  if (daysBetween > 60)
                  {
                  String outputLine2 = "The date of the expense occured" +
                        "\nmore than 60 days ago.  Are you sure this is correct?";
                  int answer = JOptionPane.showConfirmDialog(null, outputLine2, "Contiune?", JOptionPane.YES_NO_OPTION);
                  if (answer == JOptionPane.YES_OPTION) validDate = true;
                  }
                  else validDate = true;
            }
            else
            {
                  String outputLine2 = "The date " + expenseDateString + " is a future date." +
            "\nPlease enter a valid date.";
                  JOptionPane.showMessageDialog (null, outputLine2);
            }
      }while (!validDate);

      super.setCountry();
      country = super.getCountry();

      super.setConvType();
      convType = super.getConvType();

      super.setTransForm();
      switch (super.getTransForm())
      {
            case 1: meaning = "Corporate American Express";
            break;
            case 2: meaning = "Corporate Visa";
            break;
            case 3: meaning = "Corporate Mastercard";
            break;
            case 4: meaning = "Personal American Express";
            break;
            case 5: meaning = "Personal Visa";
            break;
            case 6: meaning = "Personal Mastercard";
            break;
            case 7: meaning = "Personal Check";
            break;
            case 8: meaning = "Cash";
            break;
            case 9: meaning = "Bank Transfer";
            break;
            case 10: meaning = "Travelers Check";
            break;
            case 11: meaning = "Other";
            break;
            default: meaning = "Cash";
      }

      super.setAmount();
      String expAmount = Double.toString(super.getAmount());

      //calculations
      double calculatedAmt = super.conversion();

      String amtDol = "";
      double amtIntl = 0;
      if (convType == 1)
      {
            NumberFormat currency1 = NumberFormat.getCurrencyInstance();
            amtDol = currency1.format(calculatedAmt);
            amtIntl = super.getAmount();
      }
      else if (convType == 2)
      {
            NumberFormat currency1 = NumberFormat.getCurrencyInstance();
            amtDol = currency1.format(expAmount);
            calculatedAmt = Math.round(calculatedAmt*100)/100.0;
            amtIntl = calculatedAmt;
      }

      //totals
      dollars = super.getUSD();
      totalDol = totalDol + dollars;
      NumberFormat currency = NumberFormat.getCurrencyInstance();
      usdString2 = currency.format(totalDol);

      //prepare output format
      String countryNameString = super.getCountry()+ paddingChar;
      countryNameString = countryNameString.substring(0,20);

      String currencyNameString = super.getCurrencyName() + paddingChar;
      currencyNameString = currencyNameString.substring(0,25);

      String dollarAmountString = paddingChar + amtDol;
      int stringLength = dollarAmountString.length();
      dollarAmountString = dollarAmountString.substring(stringLength-19, stringLength);

      String internationalAmountString = currency.format(amtIntl);
      internationalAmountString = paddingChar + internationalAmountString.substring(1, internationalAmountString.length());
      stringLength = internationalAmountString.length();
      internationalAmountString = internationalAmountString.substring(stringLength-19, stringLength);

      String paymentMethodString = "-------" + meaning;
      DateFormat stdDateFormat2 = DateFormat.getDateInstance(DateFormat.SHORT);


      //add lines to output array
      outputData[j][0] = countryNameString;
      outputData[j][1] = currencyNameString;
      outputData[j][2] = internationalAmountString;
      outputData[j][3] = dollarAmountString;
      outputData[j][4] = paymentMethodString;
      outputData[j][5] = stdDateFormat2.format(expenseDate);


      moreIn = JOptionPane.showInputDialog(null, "Do you wish to enter more data? (Yes or No)",
                              PaneTitle, JOptionPane.PLAIN_MESSAGE);
      if (moreIn.equalsIgnoreCase("no")) break;
      recCount++;
*******************************************

Let me know if you need more.  It would be great to extract this info.  But if I have to create another array I will.
                  }
0
 
LVL 4

Expert Comment

by:vk33
ID: 9894876
For displaying countries it's a quite simple task:

TreeSet countries = new TreeSet();
for (int i=0; i<outputData.length; i++)
   countries.add(outputData[i][0];
Iterator iter = countries.iterator();
while (iter.hasNext())
   System.out.println ((String)iter.next());

But I didn't get the point with the second summary. Do you need to calculate how many records have such payment method? I mean something like a table: Payment-method --> Number-of-records. Is it what you need?
0
Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

 

Author Comment

by:BlueTrane
ID: 9894919
> Do you need to calculate how many records have such payment method?

Yes.

I envision output to be:

Corporate American Express:  5
Corporate Visa: 4
etc: 3
etc: 2
etc: 0
etc: 0

And so on.  These should be listed in descending by counts.
0
 
LVL 92

Expert Comment

by:objects
ID: 9894969
store your summaries in Maps. eg.

Map countryCounts = new HashMap();

if (outputData[j][0]!=null && outputData[j][0].trim().length()>0)
{
   Integer count = (Integer) countryCounts.get(outputData[j][0]);
   if (count==null)
   {
      count = new Integer(0);
   }
   countryCounts.put(outputData[j][0], new Integer(count.intValue()+1));
}
0
 
LVL 4

Accepted Solution

by:
vk33 earned 125 total points
ID: 9894985
HashMap payments = new HashMap();
// counting...
for (int i=0; i<outputData.length; i++) {
   String payment = (String)outputData[i][4];
   Long num = (Long)payments.get(payment);
   if (num != null)
      payments.put(payment,new Long(num.getLongValue() + 1));
   else
      payments.put(payment,new Long(1));
}
// displaying...
for (int i=0; i<payments.size(); i++) {
   long max = 0;
   String maxKey = null;
   Iterator iter = payments.keySet().iterator();
   while (iter.hasNext()) {
      String payment = (String)iter.next();
      Long num = (Long)payments.get(payment);
      if (num.longValue() > max) {
         max = num.longValue();
         maxKey = payment;
      }
   }
   System.out.println (maxKey + ": " + max);
   payments.remove(maxKey);
}

Good luck!
0
 

Author Comment

by:BlueTrane
ID: 9894989
How do I output this?  Forgive me, I'm quite a novice.
0
 
LVL 92

Expert Comment

by:objects
ID: 9894992
0
 

Author Comment

by:BlueTrane
ID: 9894997
You posted before I hit submit...Thanks.
0
 

Author Comment

by:BlueTrane
ID: 9895020
Wow thats a lot of stuff to learn that I'm not familiar with yet.
Is there another way without using collections?
Sorry if I'm being difficult.
0
 
LVL 92

Expert Comment

by:objects
ID: 9895051
> Is there another way without using collections?

if you know the number of categories you are summarizing you could do it with arrays, but I think you'd find it a lot easier by spending a little time to understan how maps work. It's really pretty simple, a map just consists of a number of key, value pairs.
To add a new pair to a map you use:

map.put(key, value);

and to get the value associted with a key you use:

value = map.get(key);

In your case the keys are what you are summarising by eg. country name
And the values are the summary counts.
0
 

Author Comment

by:BlueTrane
ID: 9895138
objects, once again thank you.  It does seem quite simple.
I'm pretty confident I can port over your country example to work with the payment types.

You're familiar with this program.  Once everything is stored in a map, how do I extract the counts for each value?  

0
 
LVL 92

Expert Comment

by:objects
ID: 9895157
You can use an Iterator to loop thru the elements:

Iterator i = map.keySet().iterator();
while (i.hasNext())
{
   String key = (String) i.next();
   Integer value = (Integer) map.get(key);
   ...
}
0
 

Author Comment

by:BlueTrane
ID: 9895319
When I go to test to make sure value is greater than 0 it says the operator cannot be used...

I'm I just retarded or what am I doing wrong?
0
 

Author Comment

by:BlueTrane
ID: 9895355
Ok, nevermind.  I see that that test is already built in right?

How about listing these countries alphabetically before printing?
0
 

Author Comment

by:BlueTrane
ID: 9895493
Here is what I've come up with:

//country map
Map countryCounts = new HashMap();
if (outputData[j][0]!=null && outputData[j][0].trim().length()>0)
{
         String countryName = (String)outputData[j][0];
         Integer count = (Integer) countryCounts.get(countryName);
      if (count==null)
            {
                        count = new Integer(0);
               }
      countryCounts.put(outputData[j][0], new Integer(count.intValue()+1));
}

//outputs country map
Iterator iter = countryCounts.keySet().iterator();
while (iter.hasNext())
{
         String countryName = (String) iter.next();
         Integer value = (Integer) countryCounts.get(countryName);
         summary = summary + countryName +": " + value +"\n";
}

//payments map
Map paymentCounts = new HashMap();
String paymentName = (String)outputData[j][4];
Integer count2 = (Integer)paymentCounts.get(paymentName);
if (count2 == null)
      count2 = new Integer(0);
paymentCounts.put(paymentName,new Integer(count2.intValue()+1));

//outputs payment map
Iterator iter2 = paymentCounts.keySet().iterator();
while (iter2.hasNext())
{
      String payment = (String)iter2.next();
      Integer value2 = (Integer)paymentCounts.get(payment);
      summary = summary +payment +": " + value2 +"\n";
      System.out.println(summary);
}

Not quite what I want as far as output goes.  Every key,value has its own line.  I would like for it to accumulate before outputting?
0
 
LVL 4

Expert Comment

by:vk33
ID: 9895636
Hi once again. :)

Well, the code seems quite ok, but you do not sort the second summary. To make that just change a few lines:

for (int i=0; i<paymentCounts.size(); i++) {
   int max = 0;
   String maxKey = null;
   Iterator iter = paymentCounts.keySet().iterator();
   while (iter.hasNext()) {
      String payment = (String)iter.next();
      Integer num = (Integer)payments.get(payment);
      if (num.intValue() > max) {
         max = num.intValue();
         maxKey = payment;
      }
   }
   summary = summary + payment + ": " + num + "\n";
   payments.remove(maxKey);
}

Regards!
0
 

Author Comment

by:BlueTrane
ID: 9896693
hmmmm, I'm getting a null pointer error in the  new if statement...
0
 
LVL 4

Expert Comment

by:vk33
ID: 9896807
really? Could you find out the payment which has null count?

      String payment = (String)iter.next();
      Integer num = (Integer)payments.get(payment);
      if (num == null)
         System.out.println (payment + " is null");
      else if (num.intValue() > max) {
         max = num.intValue();
         maxKey = payment;
      }

The situation seems quite impossible because you put a new Integer object in both cases when initializing the map...
0
 

Author Comment

by:BlueTrane
ID: 9896925
It goes on forever saying Corporate Mastercard is null over and over.
0
 
LVL 92

Assisted Solution

by:objects
objects earned 125 total points
ID: 9899874
for (int i=0; i<paymentCounts.size(); i++) {
   int max = 0;
   String maxKey = null;
   Iterator iter = paymentCounts.keySet().iterator();
   while (iter.hasNext()) {
      String payment = (String)iter.next();
      Integer num = (Integer)payments.get(payment);
      if (num.intValue() > max) {
         max = num.intValue();
         maxKey = payment;
      }
   }
   summary = summary + payment + ": " + num + "\n";
   payments.remove(maxKey);
}

That doesn't look right, the for loop is looping over the payments summary, and then the while loop loops over it again. What is the intention here?


The NPE is because you are looping over one map, but gettin g the values out of a different one.

0
 

Author Comment

by:BlueTrane
ID: 9901199
I'll figure it out.  you guys answered my question.  I have to use a map.  Now I just have to learn it.
Thanks a lot.
0
 
LVL 92

Expert Comment

by:objects
ID: 9901420
0
 
LVL 4

Expert Comment

by:vk33
ID: 9903142
2objects:
The main idea was the following: you find the biggest value (inner while loop), print it out and remove it from the hashmap. This should be repeated as many times as the number of elements in your map (for loop). That's it! :)

Regards!
0
 
LVL 92

Expert Comment

by:objects
ID: 9906989
Would be easier to just sort the values.
0
 
LVL 4

Expert Comment

by:vk33
ID: 9909965
Yes, I was thinking this way too, maybe filling the TreeSet or something like that. But the problem is that we're interested in both key and value and the result should be sorted by value. Can you suggest the way to sort the map by value? Indeed, I didn't find an easy way for this myself. :)
0
 
LVL 92

Expert Comment

by:objects
ID: 9910010
You could try a TreeMap with a custom Comparator.
0
 
LVL 4

Expert Comment

by:vk33
ID: 9910132
afaik, TreeMap keeps the nodes sorted by the key, not the value. And I'm not sure you can implement a comparator to compare the values instead of keys. I guess it's used before placing the node in the tree thus there's no value associated with the key at that moment. Am I right?
0
 
LVL 92

Expert Comment

by:objects
ID: 9910147
You can supply your own Comparator to the TreeMap ctor.
0
 
LVL 4

Expert Comment

by:vk33
ID: 9911156
Sorry, objects, I think you can't. Comparator is applied when the node is placed in the tree. And it is applied to the Key only, Value is not touched. So, you cannot reference Value in your comparator code. Please, if I'm wrong, could you provide some code for the comparator.

Regards!
0
 
LVL 92

Expert Comment

by:objects
ID: 9916261
you could be right, was just a thought :)
0

Featured Post

MS Dynamics Made Instantly Simpler

Make Your Microsoft Dynamics Investment Count  & Drastically Decrease Training Time by Providing Intuitive Step-By-Step WalkThru Tutorials.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Java exception bubble up 2 25
Desingning Refactoring existing code 2 42
ejb mdb examples 1 36
Tagging and Merging on Branch 1 66
An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing insta…
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…
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
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:
Suggested Courses

739 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