简体   繁体   中英

How To Count The Number of Times a String Occurs

So I have created an error message for my code. Currently, my code spits out the error message each time it appears. My code validates and makes sure that an excel file is formatted correctly. After validation, it gives back error/warning messages if they occur. So when I get error messages, each message appears each time it happens. For example, the error message "Error, id must not contain special characters" happens 6 times when validating the excel file. What way is there to simply write to check if the message already occurred, and keep a counter of how many times so I can display that?

I thought about something like if (message = message) { //then create counter} but that doesn't work since message always equals message. Does anyone have any ways to do it?

EDIT: Here is a snipit of the code for validation. I want to group the messages together and not have them repeat when posting to the API.

        // if there are errors, then
        if (!errorResponse.getItems().isEmpty()) {

            // set error response
            Iterator<ErrorMessage> iter = errorResponse.getItems().iterator();

            Set<ErrorMessage> summarizedErrorMessages = new HashSet<>();

            while (iter.hasNext()) {
                ErrorMessage sem = new ErrorMessage();
                ErrorMessage em = iter.next();
                if (!summarizedErrorMessages.contains(em)) {
                    sem.setMessage(em.getMessage());
                    sem.setTotal(1);
                } else {
                    sem.setTotal(sem.getTotal() + 1);
                }
                summarizedErrorMessages.add(sem);
            }
            errorResponse.setItems(summarizedErrorMessages);
            warningResponse.setItems(new ArrayList<WarningMessage>());

A HashMap<String,Integer> will use a String 's hash code for the key, so the same String will map to the same location in the map.

So, you can just push your message strings into the map with the count of 1 when you first see it (when it's not in the map), and then increment it thereafter:

HashMap<String,Integer> messageCounts = new HashMap<>();
messages.forEach( message -> {
    messageCounts.putIfAbsent( message, 0 );
    messageCounts.computeIfPresent( message, (k,v) -> v+1 );
});

So, for your specific case it might be something like this:

// First map messages to counts
HashMap<String,Integer> messageCounts = new HashMap<>();
errorResponse.getItems().forEach( errorMessage -> {
    messageCounts.putIfAbsent( errorMessage.getMessage(), 0 );
    messageCounts.computeIfPresent( errorMessage.getMessage(), (k,v) -> v+1 );
});

// Then create the summary objects
List<ErrorMessages> summaries = 
    messageCounts.entrySet().stream().map( e -> {
        ErrorMessage summary = new ErrorMessage();
        summary.setMessage( e.getKey() );
        summary.setTotal( e.getValue() );
        return summary;
    } ).collect( Collectors.toList() );

errorResponse.setItems( summaries );

Use a HashMap<String, Long> where the key is the error message and the value is the number of times the error occured.

When receiving an error message, check if map.containsKey(message) , then get the counter ( long counter = map.get(message) ), increment it and put it back in the map ( map.put(message, counter + 1L) ).

If the map does not contain the message, add it to the map and initialize the counter to 1 ( map.put(message, 1L) ).

Something like this :

private Map<String, Long> errors = new HashMap<String, Long>();

public void handleError(String error) {
    if(errors.containsKey(error)) {
        Long counter = errors.get(error);
        errors.put(error, counter + 1L);
    } else {
        errors.put(error, 1L);
    }
}

Test :

handleError("Error, id must not contain special characters");
handleError("StackOverflow");
handleError("Error, id must not contain special characters");
handleError("Error, id must not contain special characters");
handleError("StackOverflow");

for (Map.Entry<String, Long> entry : errors.entrySet()) {
    System.out.println(entry.getKey() + " : " + entry.getValue());
}

Output :

StackOverflow : 2
Error, id must not contain special characters : 3

Just creating a seperate answer here so I can post the full code that worked for this question. Here is the code that worked with no errors:

            // if there are errors, then
        if (!errorResponse.getItems().isEmpty()) {

            // set error response
            Iterator<ErrorMessage> iter = errorResponse.getItems().iterator();

            HashMap<String, Integer> messageCounts = new HashMap<String, Integer>();
            errorResponse.getItems().forEach(ErrorMessage -> {
                messageCounts.putIfAbsent(ErrorMessage.getMessage(), 1);
                messageCounts.computeIfPresent(ErrorMessage.getMessage(), (k, v) -> v + 1);
            });

            Set<ErrorMessage> summaries = new HashSet<>();
            for (String s : messageCounts.keySet()) {
                ErrorMessage summary = new ErrorMessage();
                summary.setMessage(s);
                summary.setTotal(messageCounts.get(s));
                summaries.add(summary);
            }

            errorResponse.setItems(summaries);
            warningResponse.setItems(new ArrayList<WarningMessage>());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM