The Map Interface Flashcards

The Map Interface (13 cards)

1
Q

The Map Interface

A

A Map is an object that maps keys to values.
A map cannot contain duplicate keys.
Each key can map to at most one value.

It models the mathematical function abstraction. The Map interface includes methods for basic operations (such as put, get, remove, containsKey, containsValue, size, and empty), bulk operations (such as putAll and clear), and collection views (such as keySet, entrySet, and values).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Map implementations

A

The Java platform contains three general-purpose Map implementations: HashMap, TreeMap, and LinkedHashMap.

Their behavior and performance are precisely analogous to HashSet, TreeSet, and LinkedHashSet,

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Examples of collecting to Maps using JDK 8 aggregate operations

A

group employees by department:

// Group employees by department
Map> byDept = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment));
Or compute the sum of all salaries by department:

// Compute sum of salaries by department
Map totalByDept = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment,
Collectors.summingInt(Employee::getSalary)));
Or perhaps group students by passing or failing grades:

// Partition students into passing and failing
Map> passingFailing = students.stream()
.collect(Collectors.partitioningBy(s -> s.getGrade()>= PASS_THRESHOLD));
You could also group people by city:

// Classify Person objects by city
Map> peopleByCity
= personStream.collect(Collectors.groupingBy(Person::getCity));
Or even cascade two collectors to classify people by state and city:

// Cascade Collectors
Map» peopleByStateAndCity
= personStream.collect(Collectors.groupingBy(Person::getState,
Collectors.groupingBy(Person::getCity)))

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Map Interface Basic Operations

A

The basic operations of Map (put, get, containsKey, containsValue, size, and isEmpty) behave exactly like their counterparts in Hashtable. The following program generates a frequency table of the words found in its argument list. The frequency table maps each word to the number of times it occurs in the argument list.

import java.util.*;

public class Freq {
    public static void main(String[] args) {
        Map m = new HashMap();
        // Initialize frequency table from command line
        for (String a : args) {
            Integer freq = m.get(a);
            m.put(a, (freq == null) ? 1 : freq + 1);
        }
    System.out.println(m.size() + " distinct words:");
    System.out.println(m);
} } The only tricky thing about this program is the second argument of the put statement. That argument is a conditional expression that has the effect of setting the frequency to one if the word has never been seen before or one more than its current value if the word has already been seen. Try running this program with the command:

java Freq if it is to be it is up to me to delegate
The program yields the following output.

8 distinct words:
{to=3, delegate=1, be=1, it=2, up=1, if=1, me=1, is=2}
Suppose you’d prefer to see the frequency table in alphabetical order. All you have to do is change the implementation type of the Map from HashMap to TreeMap. Making this four-character change causes the program to generate the following output from the same command line.

8 distinct words:
{be=1, delegate=1, if=1, is=2, it=2, me=1, to=3, up=1}
Similarly, you could make the program print the frequency table in the order the words first appear on the command line simply by changing the implementation type of the map to LinkedHashMap. Doing so results in the following output.

8 distinct words:
{if=1, it=2, is=2, to=3, be=1, up=1, me=1, delegate=1}
This flexibility provides a potent illustration of the power of an interface-based framework.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

How equals and hashCode methods of two Map objects can be compared ?

A

Like the Setand Listinterfaces, Map strengthens the requirements on the equals and hashCode methods so that two Map objects can be compared for logical equality without regard to their implementation types. Two Map instances are equal if they represent the same key-value mappings.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Map constructor

A

For example, suppose you have a Map, named m. The following one-liner creates a new HashMap initially containing all of the same key-value mappings as m.

Map copy = new HashMap(m);

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Map Interface Bulk Operations

A

The clear operation does exactly what you would think it could do: It removes all the mappings from the Map.

The putAll operation is the Map analogue of the Collection interface’s addAll operation. In addition to its obvious use of dumping one Map into another, it has a second, more subtle use. Suppose a Map is used to represent a collection of attribute-value pairs; the putAll operation, in combination with the Map conversion constructor, provides a neat way to implement attribute map creation with default values. The following is a static factory method that demonstrates this technique.

static  Map newAttributeMap(Mapdefaults, Map overrides) {
    Map result = new HashMap(defaults);
    result.putAll(overrides);
    return result;
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Map Collection Views

A

The Collection view methods allow a Map to be viewed as a Collection in these three ways:

keySet — the Set of keys contained in the Map.
values — The Collection of values contained in the Map. This Collection is not a Set, because multiple keys can map to the same value.
entrySet — the Set of key-value pairs contained in the Map. The Map interface provides a small nested interface called Map.Entry, the type of the elements in this Set.
The Collection views provide the only means to iterate over a Map.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Map Collection Views example

A

This example illustrates the standard idiom for iterating over the keys in a Map with a for-each construct:

for (KeyType key : m.keySet())
System.out.println(key);
and with an iterator:

// Filter a map based on some
// property of its keys.
for (Iterator it = m.keySet().iterator(); it.hasNext(); )
if (it.next().isBogus())
it.remove();
The idiom for iterating over values is analogous. Following is the idiom for iterating over key-value pairs.

for (Map.Entry e : m.entrySet())
System.out.println(e.getKey() + “: “ + e.getValue());

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

How Collection views, calling an Iterator’s remove operation works ?

A

At first, many people worry that these idioms may be slow because the Map has to create a new Collection instance each time a Collection view operation is called. Rest easy: There’s no reason that a Map cannot always return the same object each time it is asked for a given Collection view. This is precisely what all the Map implementations in java.util do.

With all three Collection views, calling an Iterator’s remove operation removes the associated entry from the backing Map, assuming that the backing Map supports element removal to begin with. This is illustrated by the preceding filtering idiom.

With the entrySet view, it is also possible to change the value associated with a key by calling a Map.Entry’s setValue method during iteration (again, assuming the Map supports value modification to begin with). Note that these are the only safe ways to modify a Map during iteration; the behavior is unspecified if the underlying Map is modified in any other way while the iteration is in progress.

The Collection views support element removal in all its many forms — remove, removeAll, retainAll, and clear operations, as well as the Iterator.remove operation. (Yet again, this assumes that the backing Map supports element removal.)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Do we support Collection views element addition?

A

The Collection views do not support element addition under any circumstances. It would make no sense for the keySet and values views, and it’s unnecessary for the entrySet view, because the backing Map’s put and putAll methods provide the same functionality.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Fancy Uses of Collection Views: Map Algebra

A

When applied to the Collection views, bulk operations (containsAll, removeAll, and retainAll) are surprisingly potent tools. For starters, suppose you want to know whether one Map is a submap of another — that is, whether the first Map contains all the key-value mappings in the second. The following idiom does the trick.

if (m1.entrySet().containsAll(m2.entrySet())) {

}
Along similar lines, suppose you want to know whether two Map objects contain mappings for all of the same keys.

if (m1.keySet().equals(m2.keySet())) {

}
Suppose you have a Map that represents a collection of attribute-value pairs, and two Sets representing required attributes and permissible attributes. (The permissible attributes include the required attributes.) The following snippet determines whether the attribute map conforms to these constraints and prints a detailed error message if it doesn’t.

static boolean validate(Map attrMap, Set requiredAttrs, SetpermittedAttrs) {
boolean valid = true;
Set attrs = attrMap.keySet();

    if (! attrs.containsAll(requiredAttrs)) {
        Set missing = new HashSet(requiredAttrs);
        missing.removeAll(attrs);
        System.out.println("Missing attributes: " + missing);
        valid = false;
    }
    if (! permittedAttrs.containsAll(attrs)) {
        Set illegal = new HashSet(attrs);
        illegal.removeAll(permittedAttrs);
        System.out.println("Illegal attributes: " + illegal);
        valid = false;
    }
    return valid;
}
Suppose you want to know all the keys common to two Map objects.

SetcommonKeys = new HashSet(m1.keySet());
commonKeys.retainAll(m2.keySet());
A similar idiom gets you the common values.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Multimaps

A

A multimap is like a Map but it can map each key to multiple values. The Java Collections Framework doesn’t include an interface for multimaps because they aren’t used all that commonly. It’s a fairly simple matter to use a Map whose values are List instances as a multimap. This technique is demonstrated in the next code example, which reads a word list containing one word per line (all lowercase) and prints out all the anagram groups that meet a size criterion. An anagram group is a bunch of words, all of which contain exactly the same letters but in a different order. The program takes two arguments on the command line: (1) the name of the dictionary file and (2) the minimum size of anagram group to print out. Anagram groups containing fewer words than the specified minimum are not printed.

There is a standard trick for finding anagram groups: For each word in the dictionary, alphabetize the letters in the word (that is, reorder the word’s letters into alphabetical order) and put an entry into a multimap, mapping the alphabetized word to the original word. For example, the word bad causes an entry mapping abd into bad to be put into the multimap. A moment’s reflection will show that all the words to which any given key maps form an anagram group. It’s a simple matter to iterate over the keys in the multimap, printing out each anagram group that meets the size constraint.

The following program is a straightforward implementation of this technique.

import java.util.;
import java.io.
;

public class Anagrams {
    public static void main(String[] args) {
        int minGroupSize = Integer.parseInt(args[1]);
        // Read words from file and put into a simulated multimap
        Map> m = new HashMap>();
        try {
            Scanner s = new Scanner(new File(args[0]));
            while (s.hasNext()) {
                String word = s.next();
                String alpha = alphabetize(word);
                List l = m.get(alpha);
                if (l == null)
                    m.put(alpha, l=new ArrayList());
                l.add(word);
            }
        } catch (IOException e) {
            System.err.println(e);
            System.exit(1);
        }
    // Print all permutation groups above size threshold
    for (List l : m.values())
        if (l.size() >= minGroupSize)
            System.out.println(l.size() + ": " + l);
}

private static String alphabetize(String s) {
    char[] a = s.toCharArray();
    Arrays.sort(a);
    return new String(a);
} } Running this program on a 173,000-word dictionary file with a minimum anagram group size of eight produces the following output.

9: [estrin, inerts, insert, inters, niters, nitres, sinter,
triens, trines]
8: [lapse, leaps, pales, peals, pleas, salep, sepal, spale]
8: [aspers, parses, passer, prases, repass, spares, sparse,
spears]
10: [least, setal, slate, stale, steal, stela, taels, tales,
teals, tesla]
8: [enters, nester, renest, rentes, resent, tenser, ternes,
treens]
8: [arles, earls, lares, laser, lears, rales, reals, seral]
8: [earings, erasing, gainers, reagins, regains, reginas,
searing, seringa]
8: [peris, piers, pries, prise, ripes, speir, spier, spire]
12: [apers, apres, asper, pares, parse, pears, prase, presa,
rapes, reaps, spare, spear]
11: [alerts, alters, artels, estral, laster, ratels, salter,
slater, staler, stelar, talers]
9: [capers, crapes, escarp, pacers, parsec, recaps, scrape,
secpar, spacer]
9: [palest, palets, pastel, petals, plates, pleats, septal,
staple, tepals]
9: [anestri, antsier, nastier, ratines, retains, retinas,
retsina, stainer, stearin]
8: [ates, east, eats, etas, sate, seat, seta, teas]
8: [carets, cartes, caster, caters, crates, reacts, recast,
traces]

How well did you know this?
1
Not at all
2
3
4
5
Perfectly