• Java的容器类


    程序总是根据运行时才知道的某些条件去创建新对象。需要在任意时刻和任意位置创建任意数量的对象。

    如果你想保存一组基本数据类型数据,建议使用数组,但是数组有固定的尺寸。
    一般情况下,你在写程序时并不知道将需要多少个对象,或者是否需要更复杂的方式来存储对象。
    Java实用类库提供了一套完整的容器类来解决这个问题,其中基本的类型是ListSetQueueMap。这些对象类型也称为集合类容器提供了完善的方法来保存对象

    下面是完整的容器分类图:

    1.基本概念

    Java容器类类库的用途是“保存对象”,并将其划分为两个不同的概念:

    1. Collection。一个独立元素的序列。List必须按照插入的顺序保存元素,而Set不能有重复元素。Queue按照排队规则来确定对象产生的顺序。
    2. Map。一组成对的“键值对”对象,允许你使用键来查找值。
    //在创建的时候指定所使用的精确类型。
    List<Apple> apples = new ArrayList<Apple>();
    //注意:ArrayList已经被向上转型为List。使用接口的目的在于如果你决定去修改你的实现,你所需要的只是在创建出修改它。
    //List<Apple> apples = new LinkedList<Apple>();
    
    import java.util.*;
    
    public class SimpleCollection {
    	//用Integer对象填充了一个Collection,然后打印所产生的容器中的所有元素。
    	public static void main(String[] args) {
    		Collection<Integer> c = new ArrayList<Integer>();
    		for(int i = 0; i < 10; i++){
    			c.add(i); // Autoboxing
    		}
    		for(Integer i : c){
    			System.out.print(i + ", ");
    		}
    	}
    }
    /* Output:
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
    */
    

    添加一组元素

    import java.util.*;
    
    public class AddingGroups {
    	public static void main(String[] args) {
    		Collection<Integer> collection = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5));
    		Integer[] moreInts = { 6, 7, 8, 9, 10 };
    		collection.addAll(Arrays.asList(moreInts));
    		// Runs significantly faster, but you can't
    		// construct a Collection this way:
    		Collections.addAll(collection, 11, 12, 13, 14, 15);
    		Collections.addAll(collection, moreInts);
    		// Produces a list "backed by" an array:
    		List<Integer> list = Arrays.asList(16, 17, 18, 19, 20);
    		list.set(1, 99); // OK -- modify an element, list的值为 [16, 99, 18, 19, 20]
    		// list.add(21); // Runtime error because the underlying array cannot be resized.
    	}
    }
    //在java.util包中的Arrays和Collections类中都有很多实用方法,可以在一个Collection中添加一组元素。
    //Arrays.asLisst()方法接受一个数组或是一个用逗号分隔的元素列表(实用可变参数),并将其转换为一个List对象。
    

    2.容器的打印

    你必须使用Arrays.toString()来产生数组的可打印表示,但是打印容器无需任何帮助。

    import java.util.*;
    
    @SuppressWarnings("rawtypes")
    public class PrintingContainers {
    	
    	
    	static Collection fill(Collection<String> collection) {
    		collection.add("rat");
    		collection.add("cat");
    		collection.add("dog");
    		collection.add("dog");
    		return collection;
    	}
    	
    	static Map fill(Map<String,String> map) {
    	    map.put("rat", "Fuzzy");
    	    map.put("cat", "Rags");
    	    map.put("dog", "Bosco");
    	    map.put("dog", "Spot");
    	    return map;
    	}
    	
    	public static void main(String[] args) {
    	    System.out.println(fill(new ArrayList<String>()));
    	    System.out.println(fill(new LinkedList<String>()));
    	    System.out.println(fill(new HashSet<String>()));
    	    System.out.println(fill(new TreeSet<String>()));
    	    System.out.println(fill(new LinkedHashSet<String>()));
    	    System.out.println(fill(new HashMap<String,String>()));
    	    System.out.println(fill(new TreeMap<String,String>()));
    	    System.out.println(fill(new LinkedHashMap<String,String>()));
    	}
    }
    /* Output:
    [rat, cat, dog, dog]
    [rat, cat, dog, dog]
    [rat, cat, dog]
    [cat, dog, rat]
    [rat, cat, dog]
    {rat=Fuzzy, cat=Rags, dog=Spot}
    {cat=Rags, dog=Spot, rat=Fuzzy}
    {rat=Fuzzy, cat=Rags, dog=Spot}
    */
    

    3.List

    有两种类型的List

    • 基本的ArrayList,它长于随机访问元素,但是在List的中间插入和移除元素时较慢。
    • LinkedList,它通过代价较低的在List中间进行的插入和删除操作,提供了优化的顺序访问。

    List的功能方法

    4.Set

    Set不保存重复的元素。

    import java.util.*;
    
    public class SetOfInteger {
    	public static void main(String[] args) {
    		Random rand = new Random(47);
    		Set<Integer> intset = new HashSet<Integer>();
    		for(int i = 0; i < 10000; i++)
    			intset.add(rand.nextInt(30));
    		System.out.println(intset);
    	}
    }
    

    5.Map

    import java.util.*;
    
    public class Statistics {
    	
    	public static void main(String[] args) {
    		
    		Random rand = new Random(47);
    		Map<Integer,Integer> m = new HashMap<Integer,Integer>();
    		for(int i = 0; i < 10000; i++) {
    			// Produce a number between 0 and 20:
    			int r = rand.nextInt(20);
    			Integer freq = m.get(r);
    			//自动包装机制将随机生成的int转换为HashMap可以使用的Integer引用。
    			m.put(r, freq == null ? 1 : freq + 1);
    		}
    		System.out.println(m);
    	}
    }
    /* Output:
    {0=481, 1=502, 2=489, 3=508, 4=481, 5=503, 6=519, 7=471, 8=468, 9=549, 10=513, 11=531, 12=521, 13=506, 14=477, 15=497, 16=533, 17=509, 18=478, 19=464}
    */
    //键是由Random产生的数字,而值是该数字出现的次数。
    

    6.Collection和Iterator

    Collection是描述所有序列容器的共性的根接口。
    java.util.AbstractCollection类提供了Collection的默认实现。
    使用接口描述的一个理由是它可以使我们能够创建更通用的代码。

    Collection的功能方法:

    迭代器

    import typeinfo.pets.*;
    import java.util.*;
    
    public class SimpleIteration {
    	public static void main(String[] args) {
    		List<Pet> pets = Pets.arrayList(12);
    		//实现Collection就意味着需要提供iterator()方法。
    		Iterator<Pet> it = pets.iterator();
    		while(it.hasNext()) {
    			Pet p = it.next();
    			System.out.print(p.id() + ":" + p + " ");
    		}
    		System.out.println();
    		
    		//foreach语法主要用于数组,但是它也可以应用于任何Collection对象。
    		// A simpler approach, when possible:
    		for(Pet p : pets){
    			System.out.print(p.id() + ":" + p + " ");
    		}
    		System.out.println();
    		
    		// An Iterator can also remove elements:
    		it = pets.iterator();
    		for(int i = 0; i < 6; i++) {
    			it.next();
    			it.remove();
    		}
    		System.out.println(pets);
    	}
    }
    /* Output:
    0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx 8:Cymric 9:Rat 10:EgyptianMau 11:Hamster
    0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx 8:Cymric 9:Rat 10:EgyptianMau 11:Hamster
    [Pug, Manx, Cymric, Rat, EgyptianMau, Hamster]
    */
    

    Java SE5引入了新的被称为Iterable的接口,该接口包含一个能够产生Iteratoriterator()方法,并且Iterable接口被foreach用来在序列中移动。
    因此,如果你创建任何实现Iterable的类,都可以将它用于foreach语句中。

    import java.util.*;
    
    public class IterableClass implements Iterable<String> {
    	protected String[] words = ("And that is how we know the Earth to be banana-shaped.").split(" ");
    	
    	public Iterator<String> iterator() {
    		return new Iterator<String>() {
    			private int index = 0;
    			public boolean hasNext() {
    				return index < words.length;
    			}
    			public String next() { return words[index++]; }
    			public void remove() { // Not implemented
    				throw new UnsupportedOperationException();
    			}
    		};
    	}
    	
    	public static void main(String[] args) {
    		for(String s : new IterableClass())
    			System.out.print(s + " ");
    	}
    }
    /* Output:
    And that is how we know the Earth to be banana-shaped.
    */
    

    Java SE5中,大量的类都是Iterable类型,主要包括所有的Collection类(但是不包括各种Map)。

    7.散列与散列码

    ObjecthashCode()方法默认是使用对象的地址计算散列码,equals()方法默认是比较对象的地址。
    如果要使用自己的类作为HashMap的键,必须同时重载hashCode()equals()

    相关阅读:到底什么是hash?

  • 相关阅读:
    强烈推荐Seam实战
    关于写给大家看的C语言书(第2版)的读后感
    在Win7系统上安装ccnet 安装笔记
    使用Itext把html转换成pdf文件
    升级项目到Vs2010,编译时出现:MSB6006: “LC.exe”已退出,解决方法
    vs2010 插件不显示的问题处理。
    几个软件研发团队管理的小问题
    关于UML风格(第2版·英汉对照)的读后感
    C#本质论(第2版)的评论
    IDA Pro代码破解揭秘这本书怎么样
  • 原文地址:https://www.cnblogs.com/gzhjj/p/9124662.html
Copyright © 2020-2023  润新知