Solved

Summary counts for a two-dimensional array...

Posted on 2003-12-07
31
993 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
  • 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
 

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
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: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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.

757 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

22 Experts available now in Live!

Get 1:1 Help Now