Tải bản đầy đủ - 0 (trang)
10 The SortedMap<K,V> and NavigableMap<K,V> Interfaces

10 The SortedMap<K,V> and NavigableMap<K,V> Interfaces

Tải bản đầy đủ - 0trang

15.10: THE SortedMap AND NavigableMap INTERFACES



// Range-view operations

SortedMap headMap(K toKey)

SortedMap tailMap(K fromKey)

SortedMap subMap(K fromKey, K toKey)



827



Sorted set: headSet()

Sorted set: tailSet()

Sorted set: subSet()



Return set views analogous to that of a SortedSet. The set views include the

fromKey if it is present in the map, but the toKey is excluded.

// Comparator access

Comparator comparator()



Returns the key comparator, if the map has one. Otherwise returns null.



The NavigableMap Interface

Analogous to the NavigableSet interface extending the SortedSet interface, the

NavigableMap interface extends the SortedMap interface with navigation methods to

find the closest matches for specific search targets. The NavigableMap interface

replaces the SortedMap interface and is the preferred choice when a sorted map is

needed.

In addition to the methods of the SortedMap interface, the NavigableMap interface

adds the new methods shown below, where the analogous methods from the

NavigableSet interface are also identified. Note that where a NavigableMap method

returns a Map.Entry object representing a mapping, the corresponding NavigableSet method returns an element of the set.

// First-last elements

Map.Entry pollFirstEntry()

Map.Entry pollLastEntry()

Map.Entry firstEntry()

Map.Entry lastEntry()



Navigable set: pollFirst()

Navigable set: pollLast()



The pollFirstEntry() method removes and returns the first entry, and the pollLastEntry() method removes and returns the last entry currently in this navigable

map. The entry is determined according to the ordering policy employed by the

map—e.g., natural ordering. Both return null if the navigable set is empty. The

last two methods only retrieve, and do not remove, the value that is returned.

// Range-view operations

NavigableMap headMap(K toElement,

Navigable set: headSet()

boolean inclusive)

NavigableMap tailMap(K fromElement, Navigable set: tailSet()

boolean inclusive)

NavigableMap subMap(K fromElement, Navigable set: subSet()

boolean fromInclusive,

K toElement,

boolean toInclusive)



These operations are analogous to the ones in the SortedMap interface (p. 826),

returning different views of the underlying navigable map, depending on the

bound elements. However, the bound elements can be excluded or included by

the operation, depending on the value of the boolean argument inclusive.



www.it-ebooks.info



828



CHAPTER 15: COLLECTIONS AND MAPS



// Closest-matches

Map.Entry ceilingEntry(K key)

K

ceilingKey(K key)

Map.Entry floorEntry(K key)

K

floorKey(K key)

Map.Entry higherEntry(K key)

K

higherKey(K key)

Map.Entry lowerEntry(K key)

K

lowerKey(K key)



Navigable set: ceiling()

Navigable set: floor()

Navigable set: higher()

Navigable set: lower()



The ceiling methods return the least entry (or key) in the navigable map >= to

the argument key. The floor methods return the greatest entry (or key) in the

navigable map <= to the argument key. The higher methods return the least

entry (or key) in the navigable map > the argument key. The lower methods

return the greatest entry (or key) in the navigable map < the argument key. All

methods return null if there is no such key.

// Navigation

NavigableMap descendingMap()

NavigableSet descendingKeySet()

NavigableSet navigableKeySet()



Navigable set: descendingSet()



The first method returns a reverse-order view of the entries in the navigable

map. The second method returns a reverse-order key set for the entries in the

navigable map. The last method returns a forward-order key set for the entries

in the navigable map.



The TreeMap Class

The TreeMap class is the analog of the TreeSet class (p. 802), but in this case for maps.

It provides an implementation that sorts its entries in a specific order (see also Figures 15.2 and 15.3).

The TreeMap class implements the NavigableMap interface, and thereby the SortedMap

interface. By default, operations on sorted maps rely on the natural ordering of the

keys. However, a total ordering can be specified by passing a customized comparator to the constructor.

The TreeMap implementation uses balanced trees, which deliver excellent performance for all operations. However, searching in a HashMap can be faster than in a

TreeMap, as hashing algorithms usually offer better performance than the search

algorithms for balanced trees.

The TreeMap class provides four constructors, analogous to the ones in the TreeSet

class:

TreeMap()



A standard constructor used to create a new empty sorted map, according to

the natural ordering of the keys.



www.it-ebooks.info



15.10: THE SortedMap AND NavigableMap INTERFACES



829



TreeMap(Comparator c)



A constructor that takes an explicit comparator for the keys, that is used to

order the entries in the map.

TreeMap(Map m)



A constructor that can create a sorted map based on a map, according to the

natural ordering of the keys.

TreeMap(SortedMap m)



A constructor that creates a new map containing the same entries as the specified sorted map, with the same ordering for the keys.

Example 15.22 illustrates using navigable maps. It also prints a textual histogram

like the one in Example 15.21, but in addition, it prints some statistics about the

navigable map.

• An empty NavigableMap is created at (1), where the key is the

weight group and the value is the frequency.

• The procedure at (2) reads the weights specified as program arguments, converting each weight to its corresponding weight group, and the updating of the

frequency of the weight group is the same as in Example 15.21. Printing the

contents of the navigable map at (3), and its size at (4), shows that there are 7

entries ordered in ascending key order:

Group frequency map: {10=1, 60=1, 75=3, 80=1, 90=1, 95=2, 185=1}

No. of weight groups: 7



• Calls to the methods firstEntry() and lastEntry() at (5) and (6) return the following entries, respectively:

First entry: 10=1

Last entry: 185=1



• Calls to the methods floorEntry() and higherKey() with the key value 77 at (7)

and (8) return the following values, respectively:

Greatest entry <= 77: 75=3

Smallest key > 90: 95



• Calls to the methods tailMap(75, true) and headMap(75, false) at (9) and (10)

return the following map views, respectively:

Groups >= 75: {75=3, 80=1, 90=1, 95=2, 185=1}

Groups < 75: {10=1, 60=1}



• The method printHistogram() at (13) prints a histogram of the frequencies in a

navigable map:

public static int printHistogram(NavigableMap freqMap){ ... }



It is a generic method with one type parameter, K, that specifies the type of the

keys, and the type of the values (i.e., frequencies) is Integer. The method creates

an entry set at (14). Since this entry set is backed by a navigable map, traversal

of the entry set is in ascending key order. A for(:) loop is used at (15) to traverse



www.it-ebooks.info



830



CHAPTER 15: COLLECTIONS AND MAPS



the entry set, printing the histogram for the navigable map. The method also

counts the number of values on which the frequencies are based (i.e., it sums the

frequencies).

A call to the printHistogram() method at (11) with the navigable map of frequencies gives the following results:

Histogram:

10: *

60: *

75: ***

80: *

90: *

95: **

185: *

Number of weights registered: 10



It is possible to call the printHistogram() method with a map view to print partial

histograms. Based on the navigable map of frequencies in Example 15.22, the

following code:

System.out.println("Partial histogram:");

int count = printHistogram(groupFreqMap.subMap(75, true, 185, false));

System.out.println("Number of weights registered: " + count);



prints the following partial histogram:

Partial histogram:

75: ***

80: *

90: *

95: **

Number of weights registered: 7



• Polling of a navigable map is shown at (12). For each entry, its key and its

value is printed.

Histogram (by polling):

10: 1

60: 1

75: 3

80: 1

90: 1

95: 2

185: 1

Number of weights registered: 10



Polling is done directly on the navigable map, and the retrieved entry is

removed from the map. A map is not Iterable. However, an iterator or a for(:)

loop can be used to traverse a set view of the map.



www.it-ebooks.info



15.10: THE SortedMap AND NavigableMap INTERFACES



831



Example 15.22 Using Navigable Maps

import

import

import

import

import



java.util.Arrays;

java.util.Map;

java.util.NavigableMap;

java.util.Set;

java.util.TreeMap;



public class WeightGroups2 {

public static void main(String[] args) {

// Create a navigable map to store the frequency for each group.

NavigableMap groupFreqMap =

new TreeMap();

// Determine the frequencies:

for (String argument : args) {

// Get the value from an argument and group into intervals of 5.

double weight = Double.parseDouble(argument);

int weightGroup = (int) Math.round(weight/5)*5;

Integer frequency = groupFreqMap.get(weightGroup);

// Increment frequency if necessary.

frequency = (frequency == null) ? 1 : frequency+1;

groupFreqMap.put(weightGroup, frequency);

}



// (1)

// (2)



// Print statistics about the frequency map:

System.out.println("Group frequency map: " + groupFreqMap);

System.out.println("No. of weight groups: " + groupFreqMap.size());



// (3)

// (4)



System.out.println("First entry: " + groupFreqMap.firstEntry());

System.out.println("Last entry: " + groupFreqMap.lastEntry());



// (5)

// (6)



System.out.println("Greatest entry <= 77: " +

groupFreqMap.floorEntry(77));

System.out.println("Smallest key > 90: " +

groupFreqMap.higherKey(90));



// (7)

// (8)



System.out.println("Groups >= 75: " + groupFreqMap.tailMap(75, true)); // (9)

System.out.println("Groups < 75: " + groupFreqMap.headMap(75, false)); // (10)

// Print the histogram for the weight groups:

System.out.println("Histogram:");

int numRegistered = printHistogram(groupFreqMap);

// (11)

System.out.println("Number of weights registered: " + numRegistered);

// Poll the navigable map:

System.out.println("Histogram (by polling):");

int sumValues = 0;

while (!groupFreqMap.isEmpty()) {

Map.Entry entry = groupFreqMap.pollFirstEntry();

int frequency = entry.getValue();

sumValues += frequency;

System.out.printf("%5s: %s%n", entry.getKey(), frequency);

}

System.out.println("Number of weights registered: " + sumValues);

}

/** Prints histogram from a navigable map containing frequencies.

* Returns the sum of frequencies. */



www.it-ebooks.info



(12)



832



CHAPTER 15: COLLECTIONS AND MAPS

public static int printHistogram(NavigableMap freqMap) { // (13)

// Create a set of entries in ascending key order.

Set> navEntrySet = freqMap.entrySet();

// (14)

int sumValues= 0;

// Traverse the set of entries to print the histogram:

for (Map.Entry entry : navEntrySet) {

// (15)

/* Extract frequency value from entry.

* Use the Arrays.fill() method to fill a char array with equivalent

* number of ’*’ as the frequency value.

* Convert the char array to string in order to print. */

int frequency = entry.getValue();

sumValues += frequency;

char[] bar = new char[frequency];

Arrays.fill(bar, ’*’);

// Print key and bar.

System.out.printf("%5s: %s%n", entry.getKey(), new String(bar));

}

return sumValues;

}

}



Running the program with the following argument:

>java WeightGroups2 74 75 93 75 93 82 61 92 10 185



gives the following output:

Group frequency map: {10=1, 60=1, 75=3, 80=1, 90=1, 95=2, 185=1}

No. of weight groups: 7

First entry: 10=1

Last entry: 185=1

Greatest entry <= 77: 75=3

Smallest key > 90: 95

Groups >= 75: {75=3, 80=1, 90=1, 95=2, 185=1}

Groups < 75: {10=1, 60=1}

Histogram:

10: *

60: *

75: ***

80: *

90: *

95: **

185: *

Number of weights registered: 10

Histogram (by polling):

10: 1

60: 1

75: 3

80: 1

90: 1

95: 2

185: 1

Number of weights registered: 10



www.it-ebooks.info



15.10: THE SortedMap AND NavigableMap INTERFACES



833



Review Questions

15.27



Which of these methods can be called on objects implementing the Map interface?

Select the two correct answers.

(a) contains(Object o)

(b) addAll(Map m)

(c) remove(Object o)

(d) values()

(e) toArray()



15.28



Which statements are true about maps?

Select the two correct answers.

(a) The return type of the values() method is Set.

(b) Changes made in the set view returned by keySet() will be reflected in the

original map.

(c) The Map interface extends the Collection interface.

(d) All keys in a map are unique.

(e) All Map implementations keep the keys sorted.



15.29



Which of these classes have a comparator() method?

Select the two correct answers.

(a) ArrayList

(b) HashMap

(c) TreeSet

(d) HashSet

(e) TreeMap



15.30



Which methods are defined by the java.util.Map.Entry interface?

Select the two correct answers.

(a) K getKey()

(b) K setKey(K value)

(c) V getValue()

(d) V setValue(V value)

(e) void set(K key, V value)



15.31



Which statements are true about the following program?

import java.util.Collection;

import java.util.Collections;

import java.util.NavigableSet;

import java.util.TreeSet;

public class ConstructingSortedSets {

public static void main(String[] args) {



www.it-ebooks.info



834



CHAPTER 15: COLLECTIONS AND MAPS

NavigableSet navSet

= new TreeSet(Collections.reverseOrder());

Collections.addAll(navSet, 2010, 3001, 2001);

NavigableSet ss1 = new TreeSet(navSet);

NavigableSet ss2 = new TreeSet((Collection)navSet);

for (Integer iRef : navSet)

System.out.print(iRef + "|");

System.out.println();

for (Integer iRef : ss1)

System.out.print(iRef + "|");

System.out.println();

for (Integer iRef : ss2)

System.out.print(iRef + "|");

System.out.println();

while (!ss1.isEmpty())

System.out.print(ss1.pollFirst() + "|");

System.out.println();

while (!ss2.isEmpty())

System.out.print(ss2.pollFirst() + "|");



// (1)



// (2)



// (3)



// (4)



// (5)



}

}



Select the three correct answers.

(a)

(b)

(c)

(d)

(e)

15.32



The loop at (1) prints 3001|2010|2001|.

The loops at (1), (2) and (4) print the same output.

The loop at (3) prints 3001|2010|2001|.

All the loops print the same output.

The loops at (3) and (5) print the same output.



Which code, when inserted independently at (1), will result in the following output

from the program: {be=2, not=1, or=1, to=2}?

import java.util.Map;

import java.util.TreeMap;

public class FreqMap {

public static void main(String[] args) {

Map freqMap = new TreeMap();

for (String key : new String[] {"to", "be", "or", "not", "to", "be"}) {

// (1) INSERT CODE HERE ...

}

System.out.println(freqMap);

}

}



Select the two correct answers.

(a) Integer frequency = freqMap.get(key);

frequency = (frequency == 0) ? 1 : frequency+1;

freqMap.put(key, frequency);



(b) Integer frequency = freqMap.get(key);

frequency = (frequency == null) ? 1 : frequency+1;

freqMap.put(key, frequency);



www.it-ebooks.info



15.10: THE SortedMap AND NavigableMap INTERFACES



835



(c) int frequency = freqMap.get(key);

frequency = (frequency == 0) ? 1 : frequency+1;

freqMap.put(key, frequency);



(d) Integer frequency = (!freqMap.containsKey(key)) ? 1 : freqMap.get(key)+1;

freqMap.put(key, frequency);



15.33



What will the program print when compiled and run?

import

import

import

import



java.util.Collection;

java.util.Map;

java.util.NavigableMap;

java.util.TreeMap;



public class MapModify {

public static void main(String[] args)

NavigableMap grades

grades.put("A", 5); grades.put("B",

grades.put("D", 20); grades.put("E",



{

= new TreeMap();

10); grades.put("C", 15);

25);



System.out.printf("1:%d, ", grades.get(grades.firstKey()));

System.out.printf("2:%d, ", sumValues(grades.headMap("D")));

System.out.printf("3:%d, ", sumValues(grades.subMap("B", false, "D", true)));

grades.subMap(grades.firstKey(), false, grades.lastKey(), false).clear();

System.out.printf("4:%d%n", sumValues(grades));

}

public static > int sumValues(M freqMap) {

Collection values = freqMap.values();

int sumValues= 0;

for (int value : values)

sumValues += value;

return sumValues;

}

}



Select the one correct answer.

(a) 1:5, 2:50, 3:35, 4:30

(b) 1:5, 2:30, 3:35, 4:30

(c) 1:5, 2:30, 3:25, 4:30

(d) 1:5, 2:30, 3:35, 4:75

15.34



Which code, when inserted independently at (1), will result in the following output

from the program: {Soap=10, Salts=10}?

import java.util.*;

public class Mapping {

public static void main(String[] args) {

NavigableMap myMap

= new TreeMap(Collections.reverseOrder());

myMap.put("Soap", 10); myMap.put("Shampoo", 5); myMap.put("Salts", 10);

// (1) INSERT CODE HERE ...

System.out.println(myMap);

}

}



www.it-ebooks.info



836



CHAPTER 15: COLLECTIONS AND MAPS



Select the two correct answers.

(a) for (Map.Entry entry : myMap.entrySet())

if (entry.getKey().equals("Shampoo"))

myMap.remove("Shampoo");



(b) for (Iterator iterator = myMap.keySet().iterator();

iterator.hasNext();)

if (iterator.next().equals("Shampoo"))

iterator.remove();



(c) for (Iterator iterator = myMap.keySet().iterator();

iterator.hasNext();) {

if (iterator.next().equals("Shampoo"))

myMap.remove("Shampoo");



(d) for (Map.Entry entry : myMap.entrySet())

if (entry.getKey().equals("Shampoo"))

myMap.remove(entry);



(e) myMap.subMap("Shampoo", true, "Shampoo", true).clear();

15.35



Which code, when inserted independently at (1), will result in the following output

from the program: {1=Odd, 2=Even, 3=Odd}?

import java.util.Map;

import java.util.TreeMap;

public class StringBuilderMap {

public static void main(String[] args) {

Map myMap = new TreeMap();

for (Integer key : new int[] {1, 2, 1, 3, 1, 2, 3, 3}) {

// (1) INSERT CODE HERE ...

}

System.out.println(myMap);

}

private static StringBuilder toggle(StringBuilder strBuilder) {

String value = "Odd";

if (strBuilder.toString().equals(value))

value = "Even";

return strBuilder.replace(0, strBuilder.length(), value);

}

}



Select the one correct answer.

(a) StringBuilder value = myMap.get(key);

myMap.put(key, (value == null) ? new StringBuilder("Odd") :

StringBuilderMap.toggle(value));



(b) StringBuilder value = myMap.get(key);

if (value == null)

value = new StringBuilder("Odd");

else

StringBuilderMap.toggle(value);

myMap.put(key, value);



www.it-ebooks.info



15.10: THE SortedMap AND NavigableMap INTERFACES



837



(c) StringBuilder value = myMap.get(key);

if (!myMap.containsKey(key))

myMap.put(key, new StringBuilder("Odd"));

else

StringBuilderMap.toggle(value);



(d) All of the above.

15.36



Which code, when inserted independently at (1), will result in the following output

from the program: {1=Odd, 2=Even, 3=Odd}?

import java.util.Map;

import java.util.TreeMap;

public class StringMap {

public static void main(String[] args) {

Map myMap = new TreeMap();

for (Integer key : new int[] {1, 2, 1, 3, 1, 2, 3, 3}) {

// (1) INSERT CODE HERE ...

}

System.out.println(myMap);

}

private static String toggle(String str) {

if (str.equals("Odd"))

str = str.replace("Odd", "Even");

else

str = str.replace("Even", "Odd");

return str;

}

}



Select the one correct answer.

(a) String value = myMap.get(key);

myMap.put(key, (value == null) ? "Odd" : StringMap.toggle(value));



(b) String value = myMap.get(key);

if (value == null)

value = "Odd";

else

StringMap.toggle(value);

myMap.put(key, value);



(c) String value = myMap.get(key);

if (!myMap.containsKey(key))

myMap.put(key, "Odd");

else

StringMap.toggle(value);



(d) All of the above.



www.it-ebooks.info



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

10 The SortedMap<K,V> and NavigableMap<K,V> Interfaces

Tải bản đầy đủ ngay(0 tr)

×