1、集合可以理解为一个动态的数组,这个数组长度可以任意扩充,存放内容为类的对象,而不是基本类型。
2、其结构关系为:
Clloection------>List和Set ,List------------>Vector、ArrayList、LinkedList; Set----------->HashSet、TreeSet; HashSet------->LinkedHashSet
Map---------->Hashtable、HashMap、TreeMap
3、Collection接口有两个子接口,一个为Lint接口,一个为Set接口。其中Set接口存放的元素不能重复,而Link接口存放的有序且允许重复元素出现。(有序是指存放顺序与取出顺序一样)
4、Set接口及其实现类:
Set接口的容器类存储对象时,根据每个对象的哈希码值(调用hashCode()方法获得),用固定的算法算出它的存储索引,把对象放入散列表的对应位置处:如果该位置上有元素就判断是否一样(equals()方法比较),一样就不存放,不一样就存放。如果该位置没有元素就直接存放。因为存放形式是用散列表形式存放的,所以为无序存放(存放顺序和取出顺序不一致)。用散列表的好处是,在取数据时,只需算出要取对象的索引值,在比较该索引值上较少的元素即可。
另外,对于要存放到Set接口上的对象,其对应的类一定要重写equals()和hashCode(Object obj)方法以实现对象相等原则。如x.equals(y)为true,则x.hashCode的值必须和y.hashCode的值相同。但是反过来则不然,因为要存到散列表相同位置上值不一定相等,而相等的值一定会存放的相同的位置,虽然实际并不允许有存放元素出现。
HashSet类:HashSet是Set接口的一个实现类。根据元素的哈希码进行存放,允许添加null元素,不能添加重复元素。
package collection;
public class Student implements Comparable {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Student() {
this(18,"张三");
}
public Student(int age,String name){
this.age=age;
this.name=name;
}
public String toString() {
return "age: "+age+" name:"+name;
}
/**
* 重写equals()方法就一定要重写hashCode()方法
* 如果两个对象的equals()方法返回值为true,则他们的hashCode()方法返回值一定相等
*/
public boolean equals(Object o){
Student student=(Student)o;
return this.age==student.age&&
this.name.equals(student.name);//姓名年龄都一样返回true,否则为false
}
public int hashCode(){
return age*name.hashCode();
}
public int compareTo(Object o) {
Student student=(Student) o;
if (student.getAge()<this.getAge())
return -1;
else if(student.getAge()==student.getAge()){
if (student.getName().equals(this.getName())) {
return 0;
}
else {
return 1;
}
}
else
return 1;
}
}
package collection;
import java.util.HashSet;
import java.util.Iterator;
public class HashSetTest {
public static void main(String[] args) {
HashSet hashset=new HashSet();
hashset.add(new Student());
hashset.add(new Student(18,"张三"));//和缺省构造的一样,不允许重复,不被存放
hashset.add(new Student(20,"李四"));
hashset.add(new Student(22,"王二麻子"));
hashset.add(null);
hashset.add(null);//因重复元素不能存入
hashset.remove(new Student());//删除张三
/**
* 因为Collection类并没有提供get()方法,但
* Collection接口继承了Iterable<E>接口
* 所以如果要遍历Collection中的元素, 一般要采用Iterator遍历器。
* 可以通过Collection对象调用iterator方法类创建Inerator对象
*/
Iterator iterator=hashset.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
LinkedHashSet类:LinkedHashSet类是Set接口的一个实现类,根据元素的哈希码进行存放,同时用链表记录元素的加入顺序,同样允许添加null元素,不能添加重复元素。但是在取出时可以按照存放顺序进行取出,是有序的。
package collection;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
public class LinkedHashSetTest {
public static void main(String[] args) {
Collection collection =new LinkedHashSet();
Student student1=new Student();
Student student2=new Student(22,"李四");
Student student3=null;
Student student4=null;
collection.add(student2);
collection.add(student1);
collection.add(student3);
collection.add(student4);
collection.add(null);
Iterator iterator=collection.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
TreeSet类:TreeSet类是Set接口的一个实现类,使用红黑树结构对加入的元素进行顺序存放,取出时是按顺序取出的。不允许添加null元素,不允许添加重复元素。
另外需要注意的是,加入的元素必须是可排序的,对于加入元素是自定义类的对象时,该类应该继承Comparable接口,并且要实现compareTo()方法。compareTo结果要与equals一致,否则会出现错误。
package collection;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public class TreeSetTest {
/**
* 使用TreeSet容器类时,TreeSet的元素必须是可“排序”的
* 即TreeSet的自定义类元素必须实现Comparable接口的compareTo()方法
* 并且comparaTo要与equals一致,否则会在运行时报错
* 需要注意的是:null不是任何类的实例,即使e.equals(null)返回false,
* e.compareTo(null)也会抛出NullPointerException异常
* @param args
*/
public static void main(String[] args) {
Set<Student> treeSet=new TreeSet<Student>();
Student student1=new Student(22,"李四");
Student student2=new Student(18,"张三");
Student student3=new Student(11,"王二麻子");
Student student4=new Student(22,"赵五");
treeSet.add(student3);
treeSet.add(student2);
//treeSet.add(null); 不允许加入null元素
treeSet.add(new Student());
treeSet.add(student1);
treeSet.add(student4);
Iterator<Student> iterator=treeSet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
当同一类对象要有多种排序方式时,应该为该类定义不同的比较器。需要实现comparetor接口,并实现方法compare。需要注意的是在compare方法中需要充分考虑一个元素值一样的情况,否则会出错。而他的取出是有顺序的,顺序为compare方法中定义的顺序。
package collection;
public class Clerk {
private int age;
private String name;
private int wages;
public Clerk(int age,String name,int wages) {
this.age=age;
this.name=name;
this.wages=wages;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getWages() {
return wages;
}
public void setWages(int wages) {
this.wages = wages;
}
public String toString() {
return "age: "+age+" name: "+name+" wages: "+wages;
}
/**
* 重写HashCode和equals方法
* @return
*/
public int HashCode(){
return age*wages*name.hashCode();
}
public boolean equals(Object o) {
Clerk clerk=(Clerk)o;
return this.age==clerk.age&&this.wages==clerk.wages&&
this.name.equals(clerk.name);
}
}
package collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import commonly_class.runtime;
class ClerkAgeComparator implements Comparator<Clerk>{//按年龄为关键值排序
/**
* compare方法中必须写明age一样的情况,否则当元素age一样时不能存放
*/
public int compare(Clerk o1,Clerk o2){
if (o1.getAge()>o2.getAge())
return 1;
else if(o1.getAge()==o2.getAge()){
if (o1.getName().equals(o2.getName())) //一样为true
return o1.getWages()-o2.getWages();
else
return 1;
}
else
return-1;
}
}
class ClerkWagesComparator implements Comparator<Clerk>{//按工资为关键值排序
public int compare(Clerk o1,Clerk o2) {
if (o1.getWages()>o2.getWages())
return 1;
else if(o1.getWages()==o2.getWages()){
if (o1.getName().equals(o2.getName())) //一样为true
return o1.getAge()-o2.getAge();
else
return 1;
}
else
return-1;
}
}
public class VarietyComparator {
public static void main(String[] args) {
Set<Clerk> varietyComparatorTreeSet=new TreeSet<Clerk>(new ClerkAgeComparator());
Clerk clerk1=new Clerk(20, "张三", 2000);
Clerk clerk2=new Clerk(20, "李四", 2500);
Clerk clerk3=new Clerk(20, "李四", 2500);
Clerk clerk4=new Clerk(22, "李四", 5000);
Clerk clerk5=new Clerk(30, "王二麻子", 2000);
Clerk clerk6=new Clerk(35, "赵五", 2500);
varietyComparatorTreeSet.add(clerk1);
varietyComparatorTreeSet.add(clerk2);
varietyComparatorTreeSet.add(clerk3);
varietyComparatorTreeSet.add(clerk4);
varietyComparatorTreeSet.add(clerk5);
varietyComparatorTreeSet.add(clerk6);
Iterator<Clerk> iterator=varietyComparatorTreeSet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
5、List接口及其实现类:
List接口继承了Collection接口,他是一个允许存在重复项且是顺序存储的有序集合。List接口不但能够对列表的一部分进行处理,还添加了面向位置的操作,在List接口中可以从列表尾部或头部开始,如果找到元素还报告元素位置。
ArrayList类扩展AbstractList并执行List接口。ArrayList本质上是对象引用的可变长数组。也就是说ArrayList可以动态的增加或减小其大小。因为其为数组,所以方便索引,不方便增删。
package collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import javax.swing.text.StyledEditorKit.ItalicAction;
public class ArrayListTest {
public static void main(String[] args) {
Collection collection=new ArrayList();//创建一个初始容量为10的空列表
for (int i = 0; i < 5; i++) {
collection.add(new Integer(i));
}
System.out.println("collection:"+collection);
collection.add("呵呵");
Iterator iterator=collection.iterator();
while (iterator.hasNext()) {
Object object=iterator.next();
System.out.println("Iterator遍历collection "+object);
}
}
}
LinkedList类扩展AbstractSequentialList并执行List接口。它提供了一个链接列表数据结构,LinkedList容器类通过连接指针来关联前后元素。因为其为链表,所以方便增删,不方便索引。
package collection;
import java.util.LinkedList;
public class LinkedListTest {
public static void main(String[] args) {
LinkedList linkedList=new LinkedList();
linkedList.add("A");
linkedList.add("F");
linkedList.add("B");
linkedList.add(1);
System.out.println(linkedList);
linkedList.addFirst("0");
linkedList.remove("F");
System.out.println(linkedList);
}
}
Vector类提供了实现可增长数组的功能,随着更多元素的加入,数组变得更大,而在删除一些元素之后,数组变小。Vector的大学多数操作和ArrayList类相同,区别在于Vector类是线程同步的。
package collection;
import java.util.Vector;
public class VectorTest {
public static void main(String[] args) {
Vector vector=new Vector();
vector.add("one");
vector.add("two");
vector.add("three");
System.out.println(vector);
vector.setElementAt(2, 1);//修改
vector.insertElementAt(0, 0);//插入
System.out.println(vector);
vector.removeAllElements();//删除全部
System.out.println(vector);
}
}
Stack类继承自Vector类,采用堆栈方式存储。提供了push(压入)、pop(弹出)这两个基本操作方法
package collection;
import java.util.Stack;
public class StackTest {
public static void main(String[] args) {
String[] weeks=
{"周一","周二","周三","周四","周五","周六","周末"};
Stack stack=new Stack();
for (int i = 0; i < weeks.length; i++) {
stack.push(weeks[i]);//压入
}
System.out.println(stack);
System.out.println("移除站的顺序是:");
while (!stack.isEmpty()) {
System.out.println(stack.pop());//移出
}
}
}
6、Map接口及其实现类
Map接口不是Collection接口的继承。Map接口用于维护键值对,它存储的内容为键值对,描述从不重复的键到值得映射(键不能重复,通过键唯一识别)。存入Map中的映射对的“键”对应的类必须重写hashCode和equals方法。常用String作为Map的键。
HashMap类是基于哈希表的对Map接口的实现。他的内部对键采用散列表存放,所以根据键去取值得效率很高。并且他允许null值和null键的存在,但不按存入顺序取,按某种排序取
package collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class HashMapTest {
public static void main(String[] args) {
HashMap hashMap =new HashMap();
hashMap.put("3", "c");//放入
hashMap.put("4", "b");
hashMap.put("1", "c");
System.out.println(hashMap);
Set set=hashMap.keySet();//获取全部关键值,返回值为Set
Iterator iterator=set.iterator();
while (iterator.hasNext()) {
System.out.println(" 值:"+hashMap.get(iterator.next()));//查找对应的值
}
}
}
LinkedHashMap类是HashMap的子类,它可以依照插入的顺序来取元素,增、减、删、改,效率比较高。
package collection;
import java.util.LinkedHashMap;
public class LinkedHashMapTest {
public static void main(String[] args) {
LinkedHashMap linkedHashMap=new LinkedHashMap();
linkedHashMap.put("3", "c");
linkedHashMap.put("2","b");
linkedHashMap.put(null, null);
linkedHashMap.put("4","e");
System.out.println(linkedHashMap);
}
}
TreeMap类采用红黑树结构存储,要求键能排序,不按输入顺序输出。键不能为null
package collection;
import java.util.LinkedHashMap;
public class LinkedHashMapTest {
public static void main(String[] args) {
LinkedHashMap linkedHashMap=new LinkedHashMap();
linkedHashMap.put("3", "c");
linkedHashMap.put("2","b");
linkedHashMap.put(null, null);
linkedHashMap.put("4","e");
System.out.println(linkedHashMap);
}
}
Properties类继承自Hashtable,HashTable实现Map接口。Properties表示了一个持久的属性集,他可以保存在流中或从流中加载。
package collection;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class PropertiesTest {
public static void main(String[] args) {
//获取文件,并读入到输入流
InputStream inputStream=Thread.currentThread().
getContextClassLoader().getResourceAsStream("config.properties");
//创建属性对象
Properties properties=new Properties();
try {
//从流中加载数据
properties.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
String name=properties.getProperty("name");
System.out.println("name="+name);
String passWord=properties.getProperty("passWord");
System.out.println("passWord="+passWord);
/*String change="更改";
properties.setProperty(change, "genggai");
properties.setProperty("1", "a");
*/
}
}
Collections类是一个工具类,用来对集合进行操作,它主要提供一些排序算法,包括随机排序、反向排序等。
package collection;
import java.awt.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
public class CollectionsTest {
public static void printView(ArrayList arrayList){
Iterator iterator=arrayList.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
public static void main(String[] args) {
ArrayList arrayList=new ArrayList();
Student student1=new Student(22,"abc");
Student student2=new Student(18,"add");
Student student3=new Student(16,"ddcc");
Student student4=new Student(20,"abcd");
arrayList.add(student4);
arrayList.add(student3);
arrayList.add(student2);
arrayList.add(student1);
System.out.println("初始化arrayList内容:");
printView(arrayList);
Collections.shuffle(arrayList);
System.out.println("混淆后ArrayList内容:");
printView(arrayList);
Collections.sort(arrayList);
System.out.println("排序后ArrayList内容:");
printView(arrayList);
Collections.reverse(arrayList);
System.out.println("逆序后ArrayList内容:");
printView(arrayList);
}
}