开发者

How can i keep track of multiple counter variables

I have written some code that count the number of "if" statements from unknown number of files. How can i keep a count for each file separate and a total of "if" from all files?

code:

import java.io.*;

public class ifCounter4 
{
    public static void main(String[] args) throws IOException
    {
        // variable to keep track of number of if's
        int ifCount = 0;

        for (int c = 0; c < args.length; c++)
        {
            // parameter the TA will pass in
            String fileName = args[c];

            // create a new BufferReader
            BufferedReader reader = new BufferedReader( new FileReader (fileName));
            String line  = null;
            StringBuilder stringBuilder = new StringBuilder();
            String ls = System.getProperty("line.separator");

            // read from the text file
            while (( line = reader.readLine()) != null) 
            {
                stringBuilder.append(line);
                stringBuilder.append(ls);
            }

            // create a new string with stringBuilder data
            String tempString = stringBuilder.toString();

            // create one last string to look for our valid if(s) in
            // with ALL whitespace removed
            String compareString = tempString.re开发者_开发百科placeAll("\\s","");

            // check for valid if(s)
            for (int i = 0; i < compareString.length(); i++)
            {
                if (compareString.charAt(i) == ';' || compareString.charAt(i) == '}' || compareString.charAt(i) == '{') // added opening "{" for nested ifs :)
                {
                    i++;

                    if (compareString.charAt(i) == 'i')
                    {
                        i++;

                        if (compareString.charAt(i) == 'f')
                        {
                            i++;

                            if (compareString.charAt(i) == '(')
                                ifCount++;
                        } // end if
                    } // end if
                } // end if

            } // end for

         // print the number of valid "if(s) with a new line after"
         System.out.println(ifCount + " " + args[c]);  // <-- this keeps running total
                                                       // but not count for each file
        }

        System.out.println(); 

    } // end main
} // end class 


You can create a Map that stores the file names as keys and the count as values.

Map<String, Integer> count = new HashMap<String, Integer>();

After each file,

count.put(filename, ifCount);
ifcount = 0;

Walk the value set to get the total.


How about a Map which uses the file name as key and keeps the count of ifs as value? For overall count, store it in its own int, or just calculate it when needed by adding up all the values in the Map.

Map<String, Integer> ifsByFileName = new HashMap<String, Integer>();
int totalIfs = 0;
for each if in "file" {
    totalIfs++;
    Integer currentCount = ifsByFileName.get(file);
    if (currentCount == null) {
        currentCount = 0;
    }
    ifsByFileName.put(file, currentCount + 1);
}

// total from the map:
int totalIfsFromMap = 0;
for (Integer fileCount : ifsByFileName.values()) {
    totalIfsFromMap += fileCount;
}


Using an array would solve this problem.

int[] ifCount = new int[args.length]; and then in your loop ifCount[c]++;


Problematic in this scenario is when many threads want to increase the same set of counters.

Operations such as ifCount[c]++; and ifsByFileName.put(file, currentCount + 1);are not thread safe.

The obvious solution to use a ConcurrentMap and AtomicLong is also insufficient, since you must place the initial values of 0, which would require additional locking.

The Google Guava project provides a convenient out of the box sollution: AtomicLongMap

With this class you can write:

AtomicLongMap<String> cnts = AtomicLongMap.create();

cnts.incrementAndGet("foo");
cnts.incrementAndGet("bar");
cnts.incrementAndGet("foo");

for (Entry<String, Long> entry : cnts.asMap().entrySet()) {
    System.out.println(entry);
}

which prints:

foo=2
bar=1

And is completely thread safe.


This is a counter that adds to 100 and if you edit the value of N it puts a * next to the multiples of.

public class SmashtonCounter_multiples {

 public static void main(String[] args) {


    int count;
    int n = 3; //change this variable for different multiples of

    for(count = 1; count <= 100; count++) {
        if((count % n) == 0) {
                System.out.print(count + "*");
                }   
        else {
                System.out.print(count);

        if (count < 100) {
        System.out.print(",");
    }
    } 
    }

}

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜