Java - Collection

Collection层次结构

Java - Collection_第1张图片

Collection

子接口
	Set,List
集合中只能放置对象的引用,不能放置原生数据类型,
	我们需要使用原生数据类型的封装类才能加入到集合中

Ordered与Sorted接口

Ordered排序,按照某种由具体情况决定的顺序排序,是后天指定的
Sorted排序,按照天然顺序进行排序,是先天指定的

List

实现类包括
	LinkedList,Vector,ArrayList
列表接口,继承与Collection,可以按索引的顺序访问,有索引的Collection
	具有列表的功能,元素顺序均是按添加的先后进行排列的,
	允许重复的元素,允许多个null元素

List常用方法

package com.itlwc;

import java.util.ArrayList;
import java.util.List;

public class Test {
	public static void main(String[] args) {
		List list = new ArrayList();
		// 向列表的尾部追加指定的元素
		list.add("lwc");
		// 在列表的指定位置插入指定元素
		list.add(1, "nxj");
		// 追加指定 collection 中的所有元素到此列表的结尾
		list.addAll(new ArrayList());
		// 从列表中移除所有元素
		list.clear();
		// 如果列表包含指定的元素,则返回true
		list.contains("nxj");
		// 如果列表包含指定 collection 的所有元素,则返回 true
		list.containsAll(new ArrayList());
		// 比较指定的对象与列表是否相等
		list.equals(new ArrayList());
		// 返回列表中指定位置的元素
		list.get(0);
		// 返回列表的哈希码值
		list.hashCode();
		// 返回列表中首次出现指定元素的索引,如果列表不包含此元素,则返回 -1
		list.indexOf("lwc");
		// 返回列表中最后出现指定元素的索引,如果列表不包含此元素,则返回 -1
		list.lastIndexOf("lwc");
		// 如果列表不包含元素,则返回 true
		list.isEmpty();
		// 移除列表中指定位置的元素
		list.remove(0);
		// 移除列表中出现的首个指定元素
		list.remove("lwc");
		// 从列表中移除指定 collection 中包含的所有元素
		list.removeAll(new ArrayList());
		// 用指定元素替换列表中指定位置的元素
		list.set(0, "lp");
		// 返回列表中的元素数
		list.size();
		// 返回列表中指定的fromIndex(包括)和toIndex(不包括)之间的部分视图
		list.subList(1, 2);
		// 返回以正确顺序包含列表中的所有元素的数组
		list.toArray();
		// 返回以正确顺序包含列表中所有元素的数组
		list.toArray(new String[] { "a", "b" });
	}
}

ArrayList

构造方法
	public ArrayList()
	public ArrayList(int initialCapacity)
	public ArrayList(Collection c)
ArrayList依赖于数组实现的,初始长度为10的Object[],并且可随需要而增加的动态数组
	当元素超过10,那么ArrayList底层会新生成一个数组,长度为原来的1.5倍+1,
	然后将原数组内容复制到新数组中,并且后续增加的内容会放到新数组中,
	当新数组无法容纳增加的元素,重复该过程
ArrayList对随机访问性能很好,但进行大量插入,删除操作,性能很差,
	因为操作之后后续元素需要移动

遍历ArrayList

package com.itlwc;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Test {
	public static void main(String[] args) {
		List list = new ArrayList();
		list.add("lwc");
		list.add("nxj");
		// 方法一
		Iterator ite1 = list.iterator();
		while (ite1.hasNext()) {
			String str = ite1.next();
			System.out.println(str);
		}
		System.out.println("---------------------");
		// 方法二(方法一的变形)
		for (Iterator ite2 = list.iterator(); ite2.hasNext();) {
			String str = ite2.next();
			System.out.println(str);
		}
		System.out.println("---------------------");
		// 方法三
		for(String s : list){
			System.out.println(s);
		}
	}
}
/*
打印结果:
	lwc
	nxj
	---------------------
	lwc
	nxj
	---------------------
	lwc
	nxj
*/

Vector

向量,历史比较悠久,Java诞生就有了,特点与ArrayList相同,
	不同的是Vector操作元素的方法是同步的,同一时刻只能有一个线程访问,没有特殊需求都使用ArrayList
构造方法
	public Vector()
	public Vector(int initialCapacity)
	public Vector(int initialCapacity,int capacityIncrement)
		第一个参数是初始容量,第二个参数是当Vector满时的增量
	public Vector(Collection c)
Vector也是依赖数组实现的
案例
package com.itlwc;

import java.util.Enumeration;
import java.util.Vector;

public class Test {
	public static void main(String[] args) {
		Vector v = new Vector();
		v.add("123");
		v.add("lwc");
		v.add("你好");
		// Vector转换为枚举
		Enumeration e = v.elements();
		while (e.hasMoreElements()) {
			System.out.println(e.nextElement());
		}
	}
}

Stack

Vector的子类
案例
package com.itlwc;

import java.util.Enumeration;
import java.util.Stack;

public class Test {
	public static void main(String[] args) {
		Stack stack = new Stack();
		// 向栈里面压一个整数
		stack.push(new Integer(123));
		stack.push("lwc");
		stack.push(new Double(88.88));
		// 遍历
		Enumeration items = stack.elements();
		while (items.hasMoreElements()) {
			System.out.print(items.nextElement() + " ");
		}
		System.out.println();
		// 出栈
		while (stack.size() != 0) {
			System.out.print(stack.pop() + " ");
		}
	}
}
/*
打印结果:
	123 lwc 88.88 
	88.88 lwc 123
*/

LinkedList

LinkedList功能与ArrayList,Vector相同,内部是依赖双链表实现的,
	因此有很好的插入和删除性能,但随机访问元素的性能很差
构造方法
	public LinkedList()
	public LinkedList(Collection c)
LinkedList类中有一个Entry内部类,Entry内部类包含3个部分向前的引用,向后的引用,数据
	header.next = header.previous = header;

遍历LinkedList

package com.itlwc;

import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;

public class Test {
	public static void main(String[] args) {
		List link = new LinkedList();
		link.add(123);
		link.add("lwc");
		link.add(8.8);
		link.add("nxj");
		link.add(520);
		printList(link);
		printReversedList(link);
	}

	private static void printList(List link) {
		System.out.println("正序链表中的元素");
		// 的到链表的迭代器,位置指向链头
		ListIterator li = link.listIterator();
		// 判断迭代器中是否有下一个元素
		while (li.hasNext()) {
			// 返回下个元素
			System.out.print(li.next() + " ");
		}
		System.out.println();
	}

	private static void printReversedList(List link) {
		System.out.println("逆向链表中的元素");
		// 的到链表的迭代器,位置指向link.size()结尾
		ListIterator li = link.listIterator(link.size());
		// 判断迭代器中是否有前一个元素
		while (li.hasPrevious()) {
			// 返回前一个元素
			System.out.print(li.previous() + " ");
		}
		System.out.println();
	}
}
/*
打印结果:
	正序链表中的元素
	123 lwc 8.8 nxj 520 
	逆向链表中的元素
	520 nxj 8.8 lwc 123 
*/

自定义LinkedList结构

package com.itlwc;

class Node {
	Node previous;// 前驱
	String data;// 数据
	Node next;// 后驱

	public Node(String data) {
		this.data = data;
	}
}

public class Test {
	public static void main(String[] args) {
		Node node1 = new Node("node1");
		Node node2 = new Node("node2");
		Node node3 = new Node("node3");
		node1.next = node2;
		node2.previous = node1;
		node2.next = node3;
		node3.previous = node2;
		node3.next = node1;
		node1.previous = node3;

		// 增加node4
		Node node4 = new Node("node4");
		node1.next = node4;
		node4.previous = node1;
		node4.next = node2;
		node2.previous = node4;
		// 删除node4
		node1.next = node2;
		node2.previous = node1;
		node4.previous = null;
		node4.next = null;

	}
}

依赖倒置原理

依赖应该尽量在抽象层进行,避免在具体层进行,
	在实际开发中尽量使用接口类型的引用,避免采用具体类型的引用
案例
package com.itlwc;

import java.util.LinkedList;
import java.util.List;

public class Test {
	//如果我们需要传入参数是ArrayList就需要改动代码
	public void printLinkedList(LinkedList ll){
		System.out.println(ll);
	}
	//如果我们传入参数是List的子类,我们不需要改动代码,灵活性大
	public void printList(List l){
		System.out.println(l);
	}
}

将数组转换为列表

package com.itlwc;

import java.util.Arrays;
import java.util.List;

public class Test {
	public static void main(String[] args) {
		String[] str = { "l", "w", "c" };
		//使用Java类库中java.util.Arrays类的静态方法asList()
		List l = Arrays.asList(str);
		System.out.println(str);
	}

}
/*
打印结果:
	[l, w, c]
*/

ArrayList VS LinkedList

ArrayList底层采用数组实现,LinkedList底层采用双链表实现
如果为列表增加对象
	ArrayList是ArrayList底层数组维护的,LinkedList是LinkedList底层Entry对象维护的
	LinkedList底层Entry结构
		Entry{
			Entry previous;
			Object element;
			Entry next;
		}
		其中element就是我们添加的元素,最后将生成的Entry对象加入到链表中
插入和删除操作时,采用LinkedList好,搜索时,采用ArrayList好

List遍历

package com.itlwc;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class Test {
	public static void main(String[] args) {
		Map map1 = new HashMap();
		map1.put(new Integer(1), "lwc");
		map1.put(new Integer(2), "nxj");
		Map map2 = new HashMap();
		map2.put(new Integer(3), "tom");
		map2.put(new Integer(4), "cat");
		List> list = new ArrayList>();
		list.add(map1);
		list.add(map2);
		// 方法一
		Iterator> ite1 = list.iterator();
		while (ite1.hasNext()) {
			Map m = ite1.next();
			System.out.println(m);
		}
		System.out.println("-----------------------------");
		// 方法二(方法一的变形)
		for (Iterator> ite2 = list.iterator(); ite2.hasNext();) {
			Map m = ite2.next();
			System.out.println(m);
		}
		System.out.println("-----------------------------");
		// 方法三:
		for (Map m : list) {
			System.out.println(m);
		}
	}
}
/* 
打印结果: 
    {1=lwc, 2=nxj}
	{3=tom, 4=cat}
	-----------------------------
	{1=lwc, 2=nxj}
	{3=tom, 4=cat}
	-----------------------------
	{1=lwc, 2=nxj}
	{3=tom, 4=cat}
*/

Set

实现类
	HashSet,LinkedHashSet
子接口
	SortSet
	实现类
		TreeSet
不包含重复元素,最多包含一个null,元素没有顺序

HashSet

HashSet不是Ordered也不是Sorted,存储对象引用时是按照哈希策略来实现的,
	HashSet中是否存在一个对象是通过equals()和hashCode()协同判断
不保证顺序
构造方法
	public HashSet()  
	public HashSet(int initialCapacity)  
	public HashSet(Collection c)
HashSet底层是使用HashMap实现的
HashSet的add()方法详解:
	判断已经存储在集合中的对象hashCode值是否与增加对象的hashCode值一致
	如果不一致,直接加进去
	如果一致,再进行equals()比较
		如果equals()返回true,对象已经存在不增加进去
		如果equals()返回false,把对象增加进去

LinkedHashSet

LinkedHashSet是Ordered,采用双链表实现的
有固定顺序,也就是插入顺序
LinkedHashSet底层是使用LinkedHashMap实现的
构造方法
	public LinkedHashSet()  
	public LinkedHashSet(int initialCapacity)  
	public LinkedHashSet(Collection c)

SortedSet接口

保证迭代器按照元素递增顺序遍历的集合,可以按照元素的自然顺序进行排序
常用方法
	Object first()
		 返回此有序集合中当前第一个(最小的)元素
	Object last()
		返回此有序集合中最后一个(最大的)元素
	SortedSet headSet(Object toElement)
		返回此有序集合的部分视图,其元素严格小于toElement
	SortedSet tailSet(Object fromElement)
		返回此有序集合的部分视图,其元素大于或等于fromElement
	SortedSet subSet(Object fromElement,Object toElement)
		返回此有序集合的部分视图,元素范围从fromElement(包括)到toElement(不包括)
	Comparator comparator()
		返回与此有序集合关联的比较器,如果使用元素的自然顺序,则返回 null

TreeSet

TreeSet是SortedSet接口的实现,元素不论以什么元素插入,在遍历的时候,都会以天然顺序遍历
TreeSet底层是使用TreeMap实现的
构造方法
	public TreeSet()
	public TreeSet(SortedSet s)  
	public TreeSet(int initialCapacity)
	public TreeSet(Comparator)
	public TreeSet(Collection c)
因为TreeSet是带排序的,所以想要为TreeSet增加自定义类型,必须指定排序规则

TreeSet排序规则Comparator案例

package com.itlwc;

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

public class Test {
	public static void main(String[] args) {
		TreeSet set = new TreeSet(new PersonComparator());
		set.add(new Person("lwc", 80));
		set.add(new Person("nxj", 70));
		set.add(new Person("lp", 60));
		set.add(new Person("fy", 75));
		Iterator ite = set.iterator();
		while (ite.hasNext()) {
			Person p = (Person)ite.next();
			System.out.println(p.name);
		}
	}
}

class Person {
	String name;
	int score;

	public Person(String name, int score) {
		this.name = name;
		this.score = score;
	}
}

class PersonComparator implements Comparator {
	public int compare(Object o1, Object o2) {
		Person p1 = (Person) o1;
		Person p2 = (Person) o2;
		return p1.score - p2.score;
	}
}

Collections

操作Collection类的工具类,类中方法都是静态的

Collections常用方法

package com.itlwc;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Test {
	public static void main(String[] args) {
		// 将所有元素从一个列表复制到另一个列表
		Collections.copy(new ArrayList(), new ArrayList());
		// 如果两个指定collection中没有相同的元素,则返回 true
		Collections.disjoint(new ArrayList(), new ArrayList());
		// 使用指定元素替换指定列表中的所有元素
		Collections.fill(new ArrayList(), new Object());
		// 返回指定 collection 中等于指定对象的元素数
		Collections.frequency(new ArrayList(), new Object());
		// 返回指定源列表中第一次出现指定目标列表的起始位置,如果没有出现这样的列表,则返回 -1
		Collections.indexOfSubList(new ArrayList(), new ArrayList());
		// 根据元素的自然顺序,返回给定 collection 的最大元素
		Collections.max(new ArrayList());
		// //根据元素的自然顺序,返回给定 collection 的最大元素
		Collections.min(new ArrayList());
		// 使用另一个值替换列表中出现的所有某一指定值
		Collections.replaceAll(new ArrayList(), "oldVal", "newVal");
		// 反转指定列表中元素的顺序
		Collections.reverse(new ArrayList());
		// 返回一个比较器,它强行反转
		Collections.reverseOrder();
		// 返回一个比较器,它强行反转指定比较器的顺序
		Collections.reverseOrder(new Comparator() {
			@Override
			public int compare(Object o1, Object o2) {
				return 0;
			}
		});
		// 使用默认随机源随机更改指定列表的序列
		Collections.shuffle(new ArrayList());
		// 根据元素的自然顺序对指定列表按升序进行排序
		Collections.sort(new ArrayList());
		// 根据元素的自然顺序对指定列表按降序进行排序
		Collections.sort(new ArrayList(), Collections.reverseOrder());
		// 在指定列表的指定位置处交换元素
		Collections.swap(new ArrayList(), 1, 2);

	}
}

你可能感兴趣的:(JavaSE)