AnOldSoul
AnOldSoul

Reputation: 4197

What is the optimal way to check if a map contains any empty values or keys?

I have a map that stores a set of questions and answers. There cannot be questions with empty answers or answers with empty questions. Below is how I have initialized my map.

Optional<Map<String, String>> questionsAndAnswers();

I'm validating the empty strings for questions/answers in the following manner.

questionsAndAnswers().ifPresent(questionsAndAnswers -> {
        if (questionsAndAnswers.isEmpty()) {
            throw new IllegalArgumentException("questions cannot be empty if present");
        } else if (questionsAndAnswers.keySet().contains("") || questionsAndAnswers.values().contains("")) {
            throw new IllegalArgumentException("Questions or answers cannot be empty");
        }
    });

Is there a better way to achieve this? Any advice would be much appreciated.

UPDATE: There's no specific need for me to have these checks done in two separate conditions.

Upvotes: 2

Views: 10536

Answers (4)

Vedvyas Mohapatra
Vedvyas Mohapatra

Reputation: 146

You could try below

    questionsAndAnswers().ifPresent(qna -> {
        if (qna.isEmpty() || qna.containsKey("") || qna.containsValue("")) {
            throw new IllegalArgumentException("Error Message Comes Here");
        }
    });

Upvotes: 1

queeg
queeg

Reputation: 9372

First of all: The code you showed above contains some syntax errors. Probably your IDE or compiler will help you sort that out.

Your map stores key/value pairs where either key or value is the question and the other one is the answer. What you demand is there must not exist empty keys or empty values.

You can iterate through the map and find entries with empty values. What you are going to do about them is then still up to you...

for (Map.Entry<String, String> entry: questionsAndAnswers) {
    if (entry.getValue()==null || entry.getValue().isBlank()) {
        // here do what you need to do with an emty value
        // removing that from the map may be thrilling while you loop over it
    }
}

Once that is solved, you may want to care about null or empty questions. The documentation says "An object that maps keys to values. A map cannot contain duplicate keys; each key can map to at most one value." That means there is at most one emtpy question. And to find it you simply do

questionsAndAnswers.get(null); // unlikely to reveal anything at all
questionsAndAnswers.get("");   // there you go, now put this answer again with the
                               // right question. 
questionsAndAnswers.remove();  // finally remove the empty question from the map

Upvotes: 0

ses
ses

Reputation: 178

You throw two different exceptions, so there has to be a difference between an empty map and a empty Entry of the Map.

On the second if you should check, if the key or value is null or empty:

questionsAndAnswers().ifPresent(pMap -> {
            if(pMap.isEmpty())
                throw new IllegalArgumentException();
            
            if(pMap.keySet().stream().anyMatch(pKey -> pKey == null || pKey.trim().isEmpty())
                    || pMap.values().stream().anyMatch(pValue -> pValue == null || pValue.trim().isEmpty()))
                throw new IllegalArgumentException();
        });

Edit: For strings you can use Apache Commons: https://stackoverflow.com/a/14721575/11050826

Upvotes: 0

vincendep
vincendep

Reputation: 607

questionsAndAnswers().ifPresent(ConcurrentHashMap::new); throws a NullPointerException if there is any null key/value

Upvotes: 0

Related Questions