zoukankan      html  css  js  c++  java
  • 【Java】-NO.16.EBook.4.Java.1.008-【疯狂Java讲义第3版 李刚】- 集合/容器

     1.0.0 Summary

    Tittle:【Java】-NO.16.EBook.4.Java.1.008-【疯狂Java讲义第3版 李刚】- 集合

    Style:EBook

    Series:Java

    Since:2017-09-22

    End:....

    Total Hours:...

    Degree Of Diffculty:2

    Degree Of Mastery:2

    Practical Level:2

    Desired Goal:2

    Archieve Goal:....

    Gerneral Evaluation:...

    Writer:kingdelee

    Related Links:

    http://www.cnblogs.com/kingdelee/

    1.

     

     

    1.Iterator在迭代的过程中,不允许添加/删除对象,可以修改对象

    2.想要在迭代中过滤/删除某个元素,使用Predicate

    public class PredicateTest
    {
        public static void main(String[] args)
    	{
    		// 创建一个集合
    		Collection books = new HashSet();
    		books.add(new String("轻量级Java EE企业应用实战"));
    		books.add(new String("疯狂Java讲义"));
    		books.add(new String("疯狂iOS讲义"));
    		books.add(new String("疯狂Ajax讲义"));
    		books.add(new String("疯狂Android讲义"));
    		// 使用Lambda表达式(目标类型是Predicate)过滤集合
    		books.removeIf(ele -> ((String)ele).length() < 10);
    		System.out.println(books);
    	}
    }
    

      

    public class PredicateTest2
    {
        public static void main(String[] args)
    	{
    		// 创建books集合、为books集合添加元素的代码与前一个程序相同。
    		Collection books = new HashSet();
    		books.add(new String("轻量级Java EE企业应用实战"));
    		books.add(new String("疯狂Java讲义"));
    		books.add(new String("疯狂iOS讲义"));
    		books.add(new String("疯狂Ajax讲义"));
    		books.add(new String("疯狂Android讲义"));
    		// 统计书名包含“疯狂”子串的图书数量
    		System.out.println(calAll(books , ele->((String)ele).contains("疯狂")));
    		// 统计书名包含“Java”子串的图书数量
    		System.out.println(calAll(books , ele->((String)ele).contains("Java")));
    		// 统计书名字符串长度大于10的图书数量
    		System.out.println(calAll(books , ele->((String)ele).length() > 10));
    	}
    	public static int calAll(Collection books , Predicate p)
    	{
    		int total = 0;
    		for (Object obj : books)
    		{
    			// 使用Predicate的test()方法判断该对象是否满足Predicate指定的条件
    			if (p.test(obj))
    			{
    				total ++;
    			}
    		}
    		return total;
    	}
    }
    

    3.Stream提供了常用的几个数据流的操作

    public class IntStreamTest
    {
        public static void main(String[] args)
    	{
    		IntStream is = IntStream.builder()
    			.add(20)
    			.add(13)
    			.add(-2)
    			.add(18)
    			.build();
    		// 下面调用聚集方法的代码每次只能执行一个
    		System.out.println("is所有元素的最大值:" + is.max().getAsInt());
    		System.out.println("is所有元素的最小值:" + is.min().getAsInt());
    		System.out.println("is所有元素的总和:" + is.sum());
    		System.out.println("is所有元素的总数:" + is.count());
    		System.out.println("is所有元素的平均值:" + is.average());
    		System.out.println("is所有元素的平方是否都大于20:"
    			+ is.allMatch(ele -> ele * ele > 20));
    		System.out.println("is是否包含任何元素的平方大于20:"
    			+ is.anyMatch(ele -> ele * ele > 20));
    		// 将is映射成一个新Stream,新Stream的每个元素是原Stream元素的2倍+1
    		IntStream newIs = is.map(ele -> ele * 2 + 1);
    		// 使用方法引用的方式来遍历集合元素
    		newIs.forEach(System.out::println); // 输出41 27 -3 37
    	}
    }
    

    中间方法:

    filter(Predicate predicate):

    mapToXxxx(ToXxxFunction mapper):一对一进行转换

    peek(Consumer action):

    distinct()::

    sorted():

    limit(long maxSize)

    末端方法:

    forEach(Consumer action):

    toArray():

    min():

    max():

    count():

    anyMatch(Predicate predicate)

    findFirst():

    findAny();

    public class CollectionStream
    {
        public static void main(String[] args)
    	{
    		// 创建books集合、为books集合添加元素的代码与8.2.5小节的程序相同。
    		Collection books = new HashSet();
    		books.add(new String("轻量级Java EE企业应用实战"));
    		books.add(new String("疯狂Java讲义"));
    		books.add(new String("疯狂iOS讲义"));
    		books.add(new String("疯狂Ajax讲义"));
    		books.add(new String("疯狂Android讲义"));
    		// 统计书名包含“疯狂”子串的图书数量
    		System.out.println(books.stream().filter(ele->((String)ele).contains("疯狂")).count()); // 输出4
    		// 统计书名包含“Java”子串的图书数量
    		System.out.println(books.stream().filter(ele->((String)ele).contains("Java") ).count()); // 输出2
    		// 统计书名字符串长度大于10的图书数量
    		System.out.println(books.stream().filter(ele->((String)ele).length() > 10).count()); // 输出2
    		// 先调用Collection对象的stream()方法将集合转换为Stream,
    		// 再调用Stream的mapToInt()方法获取原有的Stream对应的IntStream
    		books.stream().mapToInt(ele -> ((String)ele).length())// 调用forEach()方法遍历IntStream中每个元素
    			.forEach(System.out::println);// 输出8  11  16  7  8
    
    		List<Integer> list = new ArrayList<>();
    		list.add(1);
    		list.add(3);
    		list.add(3);
    		list.add(2);
    		list.add(4);
    		list.add(4);
    		list.add(5);
    		list.add(5);
    		list.add(5);
    		System.out.println("--------1");
    		list.stream().filter(f -> f == 3).forEach(System.out::println);
    		System.out.println("--------2");
    		list.stream().distinct().forEach(System.out::println);
    		System.out.println("--------3");
    		list.stream().sorted().forEach(System.out::println);
    		System.out.println("--------4");
    		System.out.println(list.stream().min((a, b) -> a - b).get());
    		System.out.println("--------5");
    		list.stream().limit(5).forEach(System.out::println);
    		System.out.println(list.stream().count());
    		System.out.println(list.stream().anyMatch(a -> a == 5));
    		System.out.println(list.stream().findAny().get());
    		System.out.println(list.stream().findAny().get());
    		list.stream().mapToInt(a -> a*10).forEach(System.out::println);
    		list.stream().map(a -> a * a).forEach(System.out::println);
    //		list.stream().flatMap((a, b) -> a * b).forEach(System.out::println);
    
    	}
    }
    

      

    4. Set:

    Set实际上就是Collection,只是不允许添加重复元素。

    HashSet、TreeSet、EnumSet

    4.1 HashSet:

    Hash排序

    非同步

    可以存null

    比较集合中的元素是否相等的充要条件是,对应的hashcode()与equals()都要相等

    // 1.判断Set集合中两个对象相等的条件是,equals和hashcode都要一样。
    // 类A的equals方法总是返回true,但没有重写其hashCode()方法
    class A
    {
        public boolean equals(Object obj)
    	{
    		return true;
    	}
    }
    // 类B的hashCode()方法总是返回1,但没有重写其equals()方法
    class B
    {
    	public int hashCode()
    	{
    		return 1;
    	}
    }
    // 类C的hashCode()方法总是返回2,且重写其equals()方法总是返回true
    class C
    {
    	public int hashCode()
    	{
    		return 2;
    	}
    	public boolean equals(Object obj)
    	{
    		return true;
    	}
    }
    public class HashSetTest
    {
    	public static void main(String[] args)
    	{
    		HashSet books = new HashSet();
    		// 分别向books集合中添加两个A对象,两个B对象,两个C对象
    		books.add(new A());
    		books.add(new A());
    		books.add(new B());
    		books.add(new B());
    		books.add(new C());
    		books.add(new C());
    		books.forEach(System.out::println);
    	}
    }
    
    //com.lee.test.java.ebook.crazy_java.u_8_container.c_8_3_set.B@1
    //com.lee.test.java.ebook.crazy_java.u_8_container.c_8_3_set.B@1
    //com.lee.test.java.ebook.crazy_java.u_8_container.c_8_3_set.A@610455d6
    //com.lee.test.java.ebook.crazy_java.u_8_container.c_8_3_set.C@2
    //com.lee.test.java.ebook.crazy_java.u_8_container.c_8_3_set.A@511d50c0
    

      

    // 1. HashSet查找/删除元素的时候,是根据hashcode去操作的,所以有规律的重写hashcode可以避免某个撞桶
    class R
    {
        int count;
        int count2;
    	public R(int count)
    	{
    		this.count = count;
    	}
    
    	public R(int count, int count2) {
    		this.count = count;
    		this.count2 = count2;
    	}
    
    //	public String toString()
    //	{
    //		return "R[count:" + count + "]";
    //	}
    
    
    	@Override
    	public String toString() {
    		return "R{" +
    				"count=" + count +
    				", count2=" + count2 +
    				'}';
    	}
    
    	public boolean equals(Object obj)
    	{
    		if(this == obj)
    			return true;
    		if (obj != null && obj.getClass() == R.class)
    		{
    			R r = (R)obj;
    			return this.count == r.count;
    		}
    		return false;
    	}
    	public int hashCode()
    	{
    		return this.count;
    	}
    }
    public class HashSetTest2
    {
    	public static void main(String[] args)
    	{
    		HashSet hs = new HashSet();
    		hs.add(new R(5, 1));
    		hs.add(new R(-3, 2));
    		hs.add(new R(9, 3));
    		hs.add(new R(-2, 4));
    		// 打印HashSet集合,集合元素没有重复
    		System.out.println(hs);
    		// 取出第一个元素
    		Iterator it = hs.iterator();
    		R first = (R)it.next();
    		// 为第一个元素的count实例变量赋值
    		first.count = -3;     // ①
    		// 再次输出HashSet集合,集合元素有重复元素
    		System.out.println(hs);
    		// 删除count为-3的R对象
    		hs.remove(new R(-3));    // ②
    		// 可以看到被删除了一个R元素
    		System.out.println(hs);
    		System.out.println("hs是否包含count为-3的R对象?"
    			+ hs.contains(new R(-3))); // 输出false
    		System.out.println("hs是否包含count为-2的R对象?"
    			+ hs.contains(new R(-2))); // 输出false
    		System.out.println("hs是否包含count为5的R对象?"
    				+ hs.contains(new R(5))); // 输出false
    	}
    }
    

      

    6.LinkHashSet:

    LinkHashSet是HashSet的子类,根据hashcode决定存储位置,并通过链表维护元素次序使得元素插入有序。故可以有序的迭代读取元素。

    7.TreeSet:

    TreeSet是SortedSet接口的实现类,采用红黑树结构存储。排序规则:自然排序、自定义排序。

    应注意:

    7.1 TreeSet中的对象,应该是同一类型或者父子关系,且实现了Comapble接口。

    7.2 TreeSet中的对象,应实现Comaprable接口,否则再加入第二个元素时,因为排序会调用Comaprable所以会报错。

    7.3 TreeSet判断是否为同一对象,取决于compareTo()是否返回0

    class A1 implements Comparable{
    
    	@Override
    	public int compareTo(Object o) {
    		return 0;
    	}
    }
    class B1 extends A1{
    
    }
    public class TreeSetErrorTest2
    {
        public static void main(String[] args)
    	{
    		TreeSet ts = new TreeSet();
    		// 向TreeSet集合中添加两个对象
    //		ts.add(new String("疯狂Java讲义"));
    //		ts.add(new Date());   // ①
    		ts.add(new A1());   // ①
    		ts.add(new B1());   // ①
    	}
    }
    

      

    // 1. 当Set中的对象影响compareTo的元素被修改后,对该对象的删除和查找都将失效,而其他未被修改的对象正常。故不宜修改。
    class R2 implements Comparable
    {
        int count;
    	public R2(int count)
    	{
    		this.count = count;
    	}
    	public String toString()
    	{
    		return "R[count:" + count + "]";
    	}
    	// 重写equals方法,根据count来判断是否相等
    	public boolean equals(Object obj)
    	{
    		if (this == obj)
    		{
    			return true;
    		}
    		if(obj != null && obj.getClass() == R2.class)
    		{
    			R2 r = (R2)obj;
    			return r.count == this.count;
    		}
    		return false;
    	}
    	// 重写compareTo方法,根据count来比较大小
    	public int compareTo(Object obj)
    	{
    		R2 r = (R2)obj;
    		return count > r.count ? 1 :
    			count < r.count ? -1 : 0;
    	}
    }
    public class TreeSetTest3
    {
    	public static void main(String[] args)
    	{
    		TreeSet ts = new TreeSet();
    		ts.add(new R2(5));
    		ts.add(new R2(-3));
    		ts.add(new R2(9));
    		ts.add(new R2(-2));
    		// 打印TreeSet集合,集合元素是有序排列的
    		System.out.println(ts);    // ①
    		// 取出第一个元素
    		R2 first = (R2)ts.first();
    		// 对第一个元素的count赋值
    		first.count = 20;
    		// 取出最后一个元素
    		R2 last = (R2)ts.last();
    		// 对最后一个元素的count赋值,与第二个元素的count相同
    		last.count = -2;
    		// 再次输出将看到TreeSet里的元素处于无序状态,且有重复元素
    		System.out.println(ts);   // ②
    		// 删除实例变量被改变的元素,删除失败
    		System.out.println(ts.remove(new R2(-2)));   // ③
    		System.out.println(ts);
    		// 删除实例变量没有被改变的元素,删除成功
    		System.out.println(ts.remove(new R2(5)));    // ④
    		System.out.println(ts);
    	}
    }
    

      

    // 1.定制排序
    class M
    {
        int age;
    	public M(int age)
    	{
    		this.age = age;
    	}
    	public String toString()
    	{
    		return "M[age:" + age + "]";
    	}
    }
    public class TreeSetTest4
    {
    	public static void main(String[] args)
    	{
    		// 此处Lambda表达式的目标类型是Comparator
    		TreeSet ts = new TreeSet((o1 , o2) ->
    		{
    			M m1 = (M)o1;
    			M m2 = (M)o2;
    			// 根据M对象的age属性来决定大小,age越大,M对象反而越小
    			return m1.age > m2.age ? -1
    				: m1.age < m2.age ? 1 : 0;
    		});
    		ts.add(new M(5));
    		ts.add(new M(-3));
    		ts.add(new M(9));
    		System.out.println(ts);
    	}
    }
    

      

    8.EmunSet

    EmunSet

    enum Season
    {
        SPRING,SUMMER,FALL,WINTER
    }
    public class EnumSetTest
    {
    	public static void main(String[] args)
    	{
    		// 创建一个EnumSet集合,集合元素就是Season枚举类的全部枚举值
    		EnumSet es1 = EnumSet.allOf(Season.class);
    		System.out.println(es1); // 输出[SPRING,SUMMER,FALL,WINTER]
    		// 创建一个EnumSet空集合,指定其集合元素是Season类的枚举值。
    		EnumSet es2 = EnumSet.noneOf(Season.class);
    		System.out.println(es2); // 输出[]
    		// 手动添加两个元素
    		es2.add(Season.WINTER);
    		es2.add(Season.SPRING);
    		es2.add(Season.SPRING);
    		System.out.println(es2); // 输出[SPRING,WINTER]
    		// 以指定枚举值创建EnumSet集合
    		EnumSet es3 = EnumSet.of(Season.SUMMER , Season.WINTER);
    		System.out.println(es3); // 输出[SUMMER,WINTER]
    		EnumSet es4 = EnumSet.range(Season.SUMMER , Season.WINTER);
    		System.out.println(es4); // 输出[SUMMER,FALL,WINTER]
    		// 新创建的EnumSet集合的元素和es4集合的元素有相同类型,
    		// es5的集合元素 + es4集合元素 = Season枚举类的全部枚举值
    		EnumSet es5 = EnumSet.complementOf(es4);
    		System.out.println(es5); // 输出[SPRING]
    	}
    }
    

      

    public class EnumSetTest2
    {
        public static void main(String[] args)
    	{
    		Collection c = new HashSet();
    		c.clear();
    		c.add(Season.FALL);
    		c.add(Season.SPRING);
    		// 复制Collection集合中所有元素来创建EnumSet集合
    		EnumSet enumSet = EnumSet.copyOf(c);   // ①
    		System.out.println(enumSet); // 输出[SPRING,FALL]
    		c.add("疯狂Java讲义");
    		c.add("轻量级Java EE企业应用实战");
    		// 下面代码出现异常:因为c集合里的元素不是全部都为枚举值
    		enumSet = EnumSet.copyOf(c);  // ②
    	}
    }
    

      

    各种Set的实现类比较:

    8.1.在add(), get()操作,性能 HashSet > TreeSet,理由TreeSet需要额外的红黑树来维持次序。

    8.2.在add(), delete()操作,性能 HashSet > LinkedHashSet,遍历操作,性能 HashSet < LinkedHashSet,理由 LinkedHashSet有链表维护次序。

    8.3,EnumSet是性能最好的,只能保存同一种枚举类的值作为集合元素。

    8.4.HashSet,TreeSet,EnumSet都不是线程安全的,同步时应使用类似:

    TreeSet<Object> objects = new TreeSet<>();
    Collections.synchronizedNavigableSet(objects);

    9. List

    1.根据元素的equals判断List中两个元素是否相等,如果重写某元素equals=true,则该元素与集合中的任意一元素恒等。

    // 1.根据元素的equals判断List中两个元素是否相等,如果重写某元素equals=true,则该元素与集合中的任意一元素恒等。
    class A
    {
        public boolean equals(Object obj)
    	{
    		return true;
    	}
    }
    public class ListTest2
    {
    	public static void main(String[] args)
    	{
    		List books = new ArrayList();
    		books.add(new String("轻量级Java EE企业应用实战"));
    		books.add(new String("疯狂Java讲义"));
    		books.add(new String("疯狂Android讲义"));
    		System.out.println(books);
    		// 删除集合中A对象,将导致第一个元素被删除
    		books.remove(new A());     // ①
    		System.out.println(books);
    		// 删除集合中A对象,再次删除集合中第一个元素
    		books.remove(new A());     // ②
    		System.out.println(books);
    	}
    }
    //[轻量级Java EE企业应用实战, 疯狂Java讲义, 疯狂Android讲义]
    //[疯狂Java讲义, 疯狂Android讲义]
    //[疯狂Android讲义]
    

      

    public class ListTest3
    {
        public static void main(String[] args)
    	{
    		List books = new ArrayList();
    		// 向books集合中添加4个元素
    		books.add(new String("轻量级Java EE企业应用实战"));
    		books.add(new String("疯狂Java讲义"));
    		books.add(new String("疯狂Android讲义"));
    		books.add(new String("疯狂iOS讲义"));
    		// 使用目标类型为Comparator的Lambda表达式对List集合排序
    		// [疯狂iOS讲义, 疯狂Java讲义, 疯狂Android讲义, 轻量级Java EE企业应用实战]
    //		books.sort((o1, o2)->((String)o1).length() - ((String)o2).length());
    		// [轻量级Java EE企业应用实战, 疯狂Android讲义, 疯狂Java讲义, 疯狂iOS讲义]
    //		books.sort((o1, o2)->((String)o2).length() - ((String)o1).length());
    		// [疯狂iOS讲义, 疯狂Java讲义, 疯狂Android讲义, 轻量级Java EE企业应用实战]
    		books.sort(Comparator.comparing(String::length));
    		System.out.println(books);
    		// 使用目标类型为UnaryOperator的Lambda表达式来替换集合中所有元素
    		// 该Lambda表达式控制使用每个字符串的长度作为新的集合元素
    		books.replaceAll(ele->((String)ele).length());
    		System.out.println(books); // 输出[7, 8, 11, 16]
    
    	}
    }
    

      

    Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。

    // 1. Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。 
    public class ListIteratorTest
    {
        public static void main(String[] args)
    	{
    
    		String[] books = {
    			"疯狂Java讲义", "疯狂iOS讲义",
    			"轻量级Java EE企业应用实战"
    		};
    		List bookList = new ArrayList();
    		for (int i = 0; i < books.length ; i++ )
    		{
    			bookList.add(books[i]);
    		}
    
    
    		ListIterator lit = bookList.listIterator();
    		while (lit.hasNext())
    		{
    			System.out.println(lit.next());
    			lit.add("-------分隔符-------");
    		}
    		System.out.println("=======下面开始反向迭代=======");
    		while(lit.hasPrevious())
    		{
    			System.out.println(lit.previous());
    		}
    	}
    }
    

      

    10. Vector Stack ArrayList ArrayDeque

    10.1 Vector是线程安全的,ArrayList是线程不安全的,然而,要保证线程安全,只需使用Collections.synchronizedList()即可,故Vector没卵用。

    10.2 Vector是古老的类,存在诸多缺点,性能低下,远不如ArrayList,所以Vector应不使用。

    10.3 Stack是Vector的子类,模拟实现栈结构,然而远不如ArrayDeque,故Stack应不使用。

    10.4 特别注意 Arrays.ArrayList返回的是一个固定长度的数组,是Arrays里边的一个静态内部类,不是util包的ArrayList,故不能使用add remove等方法。

    11. Queue

    11.1 队列不允许随机访问,使用的是FIFO(先进先出)策略操作存储。

    11.2 Deque是双端队列的接口,可以使用实现类ArrayDeqeue LinkedList同时操作两端,ArrayDeqeue既是队列也是栈。

    11.3 PriorityQueue,queue中的异端,采取元素的大小而非FIFO的策略进行存储。

    对于ArrayDeque:

    入栈:

    push、addFirst :加头,无返回,null会异常。

    offerFirst:加头,有返回值,null会异常。调用addFirst。

    add:加头,返回boolean,null会异常。

    offer、offerLast:加尾,返回boolean,null会异常。

    出栈:

    pop、removeFirst:取头,删除。null会异常。

    peek、peekFirst:取头,不删除。null返null。

    peekLast:取尾,不删除。null返null

    public class PriorityQueueTest
    {
        public static void main(String[] args)
    	{
    		PriorityQueue pq = new PriorityQueue();
    		// 下面代码依次向pq中加入四个元素
    		pq.offer(6);
    		pq.offer(-3);
    		pq.offer(20);
    		pq.offer(18);
    		// 输出pq队列,并不是按元素的加入顺序排列
    		System.out.println(pq); // 输出[-3, 6, 20, 18]
    		// 访问队列第一个元素,其实就是队列中最小的元素:-3
    		System.out.println(pq.poll());
    	}
    }
    
    
    public class LinkedListTest
    {
        public static void main(String[] args)
    	{
    		LinkedList books = new LinkedList();
    		// 将字符串元素加入队列的尾部
    		books.offer("疯狂Java讲义");
    		// 将一个字符串元素加入栈的顶部
    		books.push("轻量级Java EE企业应用实战");
    		// 将字符串元素添加到队列的头部(相当于栈的顶部)
    		books.offerFirst("疯狂Android讲义");
    		// 以List的方式(按索引访问的方式)来遍历集合元素
    		for (int i = 0; i < books.size() ; i++ )
    		{
    			System.out.println("遍历中:" + books.get(i));
    		}
    		// 访问、并不删除栈顶的元素
    		System.out.println(books.peekFirst());
    		// 访问、并不删除队列的最后一个元素
    		System.out.println(books.peekLast());
    		// 将栈顶的元素弹出“栈”
    		System.out.println(books.pop());
    		// 下面输出将看到队列中第一个元素被删除
    		System.out.println(books);
    		// 访问、并删除队列的最后一个元素
    		System.out.println(books.pollLast());
    		// 下面输出:[轻量级Java EE企业应用实战]
    		System.out.println(books);
    	}
    }
    
    public class ArrayDequeStack
    {
        public static void main(String[] args)
    	{
    		ArrayDeque stack = new ArrayDeque();
    		// 依次将三个元素push入"栈"
    		stack.push("1");
    //		stack.push("3");
    //		stack.push("4");
    //		stack.push("2");
    //		stack.push("5");
    
    		// add与Off是一样的方法
    		stack.addFirst("8");
    		stack.offer("8");
    		stack.add("8");
    		stack.addFirst("8");
    		stack.addLast("8");
    		stack.offer("8");
    
    		//
    		System.out.println(stack);
    		System.out.println(stack.peekLast());
    		System.out.println(stack.pop());
    		System.out.println(stack.peekLast());
    		System.out.println(stack);
    	}
    }
    
    
    public class ArrayDequeQueue
    {
        public static void main(String[] args)
    	{
    		ArrayDeque queue = new ArrayDeque();
    		// 依次将三个元素加入队列
    		queue.offer("疯狂Java讲义");
    		queue.offer("轻量级Java EE企业应用实战");
    		queue.offer("疯狂Android讲义");
    		// 输出:[疯狂Java讲义, 轻量级Java EE企业应用实战, 疯狂Android讲义]
    		System.out.println(queue);
    		// 访问队列头部的元素,但并不将其poll出队列"栈",输出:疯狂Java讲义
    		System.out.println(queue.peek());
    		// 依然输出:[疯狂Java讲义, 轻量级Java EE企业应用实战, 疯狂Android讲义]
    		System.out.println(queue);
    		// poll出第一个元素,输出:疯狂Java讲义
    		System.out.println(queue.poll());
    		// 输出:[轻量级Java EE企业应用实战, 疯狂Android讲义]
    		System.out.println(queue);
    	}
    }
    

      

    12. ArrayList LinkedList

    ArrayList 基于数组的线性表,以一块连续内存区保存所有元素,具有较好的随机访问效率。遍历使用get获取元素。

    LinkedList 基于链表的线性表,在插入、删除元素时具有较好效率。遍历时使用Iterator。

    13.Map

     

    13.1 HashMap Hashtable

    Hashtable与Vector一样都是过时的玩意,同步也没卵用,用 Collections.synchronizedMap() 就能够使HashMap具备同步效果。

    class A
    {
        int count;
    	public A(int count)
    	{
    		this.count = count;
    	}
    	// 根据count的值来判断两个对象是否相等。
    	public boolean equals(Object obj)
    	{
    		if (obj == this)
    			return true;
    		if (obj != null && obj.getClass() == A.class)
    		{
    			A a = (A)obj;
    			return this.count == a.count;
    		}
    		return false;
    	}
    	// 根据count来计算hashCode值。
    	public int hashCode()
    	{
    		return this.count;
    	}
    }
    class B
    {
    	// 重写equals()方法,B对象与任何对象通过equals()方法比较都返回true
    	public boolean equals(Object obj)
    	{
    		return true;
    	}
    }
    public class HashtableTest
    {
    	public static void main(String[] args)
    	{
    		Hashtable ht = new Hashtable();
    		ht.put(new A(60000) , "疯狂Java讲义");
    		ht.put(new A(87563) , "轻量级Java EE企业应用实战");
    		ht.put(new A(1232) , new B());
    		System.out.println(ht);
    		// 只要两个对象通过equals比较返回true,
    		// Hashtable就认为它们是相等的value。
    		// 由于Hashtable中有一个B对象,
    		// 它与任何对象通过equals比较都相等,所以下面输出true。
    		System.out.println(ht.containsValue("测试字符串")); // ① 输出true
    		// 只要两个A对象的count相等,它们通过equals比较返回true,且hashCode相等
    		// Hashtable即认为它们是相同的key,所以下面输出true。
    		System.out.println(ht.containsKey(new A(87563)));   // ② 输出true
    		// 下面语句可以删除最后一个key-value对
    		ht.remove(new A(1232));    //③
    		System.out.println(ht);
    	}
    }
    

      

    // 1.当用于equals判断的值被修改时,该元素就无法被操作
    public class HashMapErrorTest
    {
        public static void main(String[] args)
    	{
    		HashMap ht = new HashMap();
    		// 此处的A类与前一个程序的A类是同一个类
    		ht.put(new A(60000) , "疯狂Java讲义");
    		ht.put(new A(87563) , "轻量级Java EE企业应用实战");
    		System.out.println("--------------1:" + ht);
    		// 获得Hashtable的key Set集合对应的Iterator迭代器
    		Iterator it = ht.keySet().iterator();
    		// 取出Map中第一个key,并修改它的count值
    		A first = (A)it.next();
    		first.count = 87563;   // ①
    		// 输出{A@1560b=疯狂Java讲义, A@1560b=轻量级Java EE企业应用实战}
    		System.out.println("--------------2:" + ht);
    		// 只能删除没有被修改过的key所对应的key-value对
    		ht.remove(new A(87563));
    
    		System.out.println("--------------3:" + ht);
    		// 无法获取剩下的value,下面两行代码都将输出null。
    		System.out.println(ht.get(new A(87563)));   // ② 输出null
    		System.out.println(ht.get(new A(60000)));   // ③ 输出null
    	}
    }
    //--------------1:{com.lee.test.java.ebook.crazy_java.u_8_container.c_8_6_map.A@ea60=疯狂Java讲义, com.lee.test.java.ebook.crazy_java.u_8_container.c_8_6_map.A@1560b=轻量级Java EE企业应用实战}
    //--------------2:{com.lee.test.java.ebook.crazy_java.u_8_container.c_8_6_map.A@1560b=疯狂Java讲义, com.lee.test.java.ebook.crazy_java.u_8_container.c_8_6_map.A@1560b=轻量级Java EE企业应用实战}
    //--------------3:{com.lee.test.java.ebook.crazy_java.u_8_container.c_8_6_map.A@1560b=疯狂Java讲义}
    //null
    //null
    

      

     13.2 LinkedHashMap

    13.2.1 LinkedHashMap 是 HashMap的子类,如同LinkedHashSet是HashSet的子类一样,用双向链表维护key-value的顺序,使得迭代的顺序与插入的顺序是一致的。

    13.2.2 LinkedHashMap 不用像HashMap一样靠hash控制key-value顺序,同时有避免TreeMap增加的成本,因为要维护插入顺序,故插入速度低于HashMap,但迭代速度要优于HashMap

    public class LinkedHashMapTest
    {
        public static void main(String[] args)
    	{
    		LinkedHashMap scores = new LinkedHashMap();
    		scores.put("语文" , 80);
    		scores.put("英文" , 82);
    		scores.put("数学" , 76);
    		// 调用forEach方法遍历scores里的所有key-value对
    		scores.forEach((key, value) -> System.out.println(key + "-->" + value));
    	}
    }
    

      

     14. Properties

    Properties是Hashtable的子类

    public class PropertiesTest
    {
        public static void main(String[] args)
    		throws Exception
    	{
    		Properties props = new Properties();
    		// 向Properties中增加属性
    		props.setProperty("username" , "yeeku");
    		props.setProperty("password" , "123456");
    		// 将Properties中的key-value对保存到a.ini文件中
    		props.store(new FileOutputStream("a.ini")
    			, "comment line");   //①
    		// 新建一个Properties对象
    		Properties props2 = new Properties();
    		// 向Properties中增加属性
    		props2.setProperty("gender" , "male");
    		// 将a.ini文件中的key-value对追加到props2中
    		props2.load(new FileInputStream("a.ini") );   //②
    		System.out.println(props2);
    	}
    }
    

      

     15.SortedMap

    SortedMap是Map的子类接口,TreeMap是接口SortedMap的实现类,与TreeSet的SortedSet关系一样,红黑树结构控制存储。

     

     1.定制排序,传入Comparator的实现类实现compare(a,b)的方法

     2.自然排序,让TreeMap中的key元素对象实现Comparable的compareTo(O o)方法

    class R implements Comparable
    {
        int count;
    	public R(int count)
    	{
    		this.count = count;
    	}
    	public String toString()
    	{
    		return "R[count:" + count + "]";
    	}
    	// 根据count来判断两个对象是否相等。
    	public boolean equals(Object obj)
    	{
    		if (this == obj)
    			return true;
    		if (obj != null	&& obj.getClass() == R.class)
    		{
    			R r = (R)obj;
    			return r.count == this.count;
    		}
    		return false;
    	}
    	// 根据count属性值来判断两个对象的大小。
    	public int compareTo(Object obj)
    	{
    		R r = (R)obj;
    		return count > r.count ? 1 :
    			count < r.count ? -1 : 0;
    	}
    }
    // 1.定制排序,传入Comparator的实现类实现compare(a,b)的方法
    // 2.自然排序,让TreeMap中的key元素对象实现Comparable的compareTo(O o)方法
    public class TreeMapTest
    {
    	public static void main(String[] args)
    	{
    		TreeMap tm = new TreeMap((a, b) -> (int)b - (int)a);
    		tm.put(new R(3) , "轻量级Java EE企业应用实战");
    		tm.put(new R(-5) , "疯狂Java讲义");
    		tm.put(new R(9) , "疯狂Android讲义");
    		System.out.println(tm);
    		// 返回该TreeMap的第一个Entry对象
    		System.out.println(tm.firstEntry());
    		// 返回该TreeMap的最后一个key值
    		System.out.println(tm.lastKey());
    		// 返回该TreeMap的比new R(2)大的最小key值。
    		System.out.println(tm.higherKey(new R(2)));
    		// 返回该TreeMap的比new R(2)小的最大的key-value对。
    		System.out.println(tm.lowerEntry(new R(2)));
    		// 返回该TreeMap的子TreeMap
    		System.out.println(tm.subMap(new R(-1) , new R(4)));
    	}
    }
    

      

    16.WeakHashMap

    与HsahMap的区别在于,HashMap里边对key的存储是强引用,而WeakHashMap是弱引用。即进行GC后,WeakHashMap里边的key因为不是强引用,而有可能会回收。缓冲区的除外。

    // 1.new String()只保留了弱引用,而""是字符串缓冲区的,不会被GC。
    public class WeakHashMapTest
    {
        public static void main(String[] args)
    	{
    		WeakHashMap whm = new WeakHashMap();
    		// 将WeakHashMap中添加三个key-value对,
    		// 三个key都是匿名字符串对象(没有其他引用)
    		whm.put(new String("语文") , new String("良好"));
    		whm.put(new String("数学") , new String("及格"));
    		whm.put(new String("英文") , new String("中等"));
    		//将 WeakHashMap中添加一个key-value对,
    		// 该key是一个系统缓存的字符串对象。
    		whm.put("java" , new String("中等"));    // ①
    		// 输出whm对象,将看到4个key-value对。
    		System.out.println(whm);
    		// 通知系统立即进行垃圾回收
    		System.gc();
    		System.runFinalization();
    		// 通常情况下,将只看到一个key-value对。
    		System.out.println(whm);
    	}
    }
    //{英文=中等, java=中等, 数学=及格, 语文=良好}
    //{java=中等}
    

      

    17.IdentityHashMap

    IdentityHashMap 判断相等需要key1 == key2 严格相等才可以,而HashMap只需要key1和key2通过equals比较相等且hashcode相等。

    public class IdentityHashMapTest
    {
        public static void main(String[] args)
    	{
    		IdentityHashMap ihm = new IdentityHashMap();
    		// 下面两行代码将会向IdentityHashMap对象中添加两个key-value对
    		ihm.put(new String("语文") , 89);
    		ihm.put(new String("语文") , 78);
    		// 下面两行代码只会向IdentityHashMap对象中添加一个key-value对
    		ihm.put("java" , 93);
    		ihm.put("java" , 98);
    		System.out.println(ihm);
    	}
    }
    //{语文=78, java=98, 语文=89}
    

      

     

     18.EnumMap

    Enum内部以数组实现,所以非常高效

    enum Season
    {
        SPRING,SUMMER,FALL,WINTER
    }
    public class EnumMapTest
    {
    	public static void main(String[] args)
    	{
    		// 创建EnumMap对象,该EnumMap的所有key都是Season枚举类的枚举值
    		EnumMap enumMap = new EnumMap(Season.class);
    		enumMap.put(Season.SUMMER , "夏日炎炎");
    		enumMap.put(Season.SPRING , "春暖花开");
    		System.out.println(enumMap);
    	}
    }
    

      

     桶概念:

    HashMap和HashSet通过hash算法存储key元素,而这个key有可能会有重复的情况,所以用了一个集合桶去装这些重复的hash值的元素。相同的桶里边的元素之间是通过链表实现的,必须按顺序存储,故桶内的查找效率就会低了。

  • 相关阅读:
    hdu1242 Rescue BFS广搜 + 优先队列
    hdu 1430 魔板
    康托展开
    hdu 4394 Digital Square(bfs)
    hdu 1969 Pie
    KMP模板
    hdu 1846 Brave Game
    循环赛日程表
    hdu 1022 Train Problem I
    整数划分问题
  • 原文地址:https://www.cnblogs.com/kingdelee/p/7577634.html
Copyright © 2011-2022 走看看