Answers to Questions and Exercises:
Questions
- Question: You plan to write a program that uses several basic collection interfaces:
Set
,List
,Queue
, andMap
. You're not sure which implementations will work best, so you decide to use general-purpose implementations until you get a better idea how your program will work in the real world. Which implementations are these?
Answer:
Set
:HashSet
List
:ArrayList
Queue
:LinkedList
Map
:HashMap
- Question: If you need a
Set
implementation that provides value-ordered iteration, which class should you use?
Answer:
TreeSet
guarantees that the sorted set is in ascending element order, sorted according to the natural order of the elements or by theComparator
provided. - Question: Which class do you use to access wrapper implementations?
Answer:
You use theCollections
class, which provides static methods that operate on or return collections.
Exercises
- Exercise: Write a program that reads a text file, specified by the first command line argument, into a
List
. The program should then print random lines from the file, the number of lines printed to be specified by the second command line argument. Write the program so that a correctly-sized collection is allocated all at once, instead of being gradually expanded as the file is read in. Hint: To determine the number of lines in the file, usejava.io.File.length
to obtain the size of the file, then divide by an assumed size of an average line.
Answer:
Since we are accessing theList
randomly, we will useArrayList
. We estimate the number of lines by taking the file size and dividing by 50. We then double that figure, since it is more efficient to overestimate than to underestmate.import java.util.*; import java.io.*; public class FileList { public static void main(String[] args) { final int assumedLineLength = 50; File file = new File(args[0]); List<String> fileList = new ArrayList<String>((int)(file.length() / assumedLineLength) * 2); BufferedReader reader = null; int lineCount = 0; try { reader = new BufferedReader(new FileReader(file)); for (String line = reader.readLine(); line != null; line = reader.readLine()) { fileList.add(line); lineCount++; } } catch (IOException e) { System.err.format("Could not read %s: %s%n", file, e); System.exit(1); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) {} } } int repeats = Integer.parseInt(args[1]); Random random = new Random(); for (int i = 0; i < repeats; i++) { System.out.format("%d: %s%n", i, fileList.get(random.nextInt(lineCount - 1))); } } }
ArrayList
has little affect on its performance. Specifying an initial capacity in advance is more likely to be useful when your program repeatly creates largeArrayList
objects without intervening I/O.