一:Java集合产生的原因
一方面,面向对 象语言对事物的体现 都是以对象的形式,为了方便对多 个对象的操作,就要对对象进行存储。 另-方面,使用Array存储对 象方面具有一些弊端,大小不能动态改变,而Java 集合就像一 种容器,可以动态地把多 个对象的引用放入容器中。所以,Java集合类可以用于存储数量不等的多个对象,还可用于保存具有映射关系的关联数组。
二:集合架构体系图
●Java集合可分为Collection和Map两种体系
➢Collection接口:
➢Set:元素无序、不可重复的集合--类似高中的"集合”
➢List:元素有序,可重复的集合--”动态”数组
➢Map接口:具有映射关系“key-value对” 的集合--类似于高中的“函数”y=f(x) (x1,y1) (x2,y2)
三:Collection接口
●Collection接口是List、Set 和Queue接口的父接口,该接口里定义的方法既可用于操作Set集合,也可用于操作List和Queue集合。
3.1:List接口
Java中数组用来存储数据的局限性,List集合类中元素有序、且可重复,集合中的每个元素都有其对应的顺序索引。List容器中的元素都对应一个整数型的序号记载其在容器中的位置,
可以根据序号存取容器中的元素。JDK API中List接口的实现类常用的有: ArrayList、 LinkedList和Vector。
list集合中的元素或对象(主要是自己的实现类)要重写equals方法,因为equals方法是判断两个对象相等的条件,不重写可能导致相等的对象无法判断相等
1 packageSet;2 importorg.junit.Test;3
4 import java.util.*;5
6 /*
7 * 1.存储对象可以考虑:①数组 ②集合8 * 2.数组存储对象的特点:Student[] stu = new Student[20]; stu[0] = new Student();....9 * >弊端:①一旦创建,其长度不可变。②真实的数组存放的对象的个数是不可知。10 * 3.集合11 * Collection接口12 * |------List接口:存储有序的,可以重复的元素13 * |------ArrayList(主要的实现类)、LinkedList(对于频繁的插入、删除操作)、Vector(古老的实现类、线程安全的)14 * |------Set接口:存储无序的,不可重复的元素15 * |------HashSet、LinkedHashSet、TreeSet16 * Map接口:存储“键-值”对的数据17 * |-----HashMap、LinkedHashMap、TreeMap、Hashtable(子类:Properties)18 */
19 public classCollectionTest {20 @Test21 public voidtestCollection1() {22 //size()方法判断集合的大小,add(Object obj)用来向集合添加元素,addAll(Collection coll),将一个集合中的所有元素添加到另一个集合里面23 //isEmpty()用来判断集合是否为空,clear()用来清空集合里的元素,contains用来判断集合是否包含指定的obj元素,对于自定义类对象要重写equals作为判断的依据24 //containsAll(Collection coll):判断当前集合中是否包含coll中所有的元素,retainAll(Collection coll):求当前集合与coll的共有的元素,返回给当前集合25 //equals判断两个集合中元素是否相同,toArray()变成数组,Arrays.toList()数组变成集合,集合可以通过.iterator()来进行遍历元素,包含next和hasnext方法,也可以增强for循环
26 Collection coll = newArrayList();27 coll.add(1);28 coll.add("hello");29 coll.add(new Person("nihao",12));//添加元素
30 System.out.println(coll.size());//判断大小,
31 coll.add(1);32 System.out.println(coll.size());//重复的元素可以添加
33 ArrayList arrayList = newArrayList();34 arrayList.add(10);35 coll.addAll(arrayList);//添加一个集合
36 System.out.println(coll.isEmpty());//判断是否为空
37 boolean b = (boolean) arrayList.remove(Integer.valueOf(10));//删除元素10,注意数字是表示按照下标进行删除,包装类则是安装元素进行删除
38 System.out.println(b);39 System.out.println(arrayList.isEmpty());//现在为空40 //coll.clear();//清空元素,41 //System.out.println(coll);
42 System.out.println(coll.contains(Integer.valueOf(1)));//包含一个元素
43 arrayList.add(1);44 System.out.println(coll.containsAll(arrayList));//包含一个集合
45 System.out.println(coll.retainAll(arrayList));//求交集
46 System.out.println(coll.equals(arrayList));//判断两个集合是否相同
47 System.out.println(arrayList.hashCode());//集合的hashcode值
48 arrayList.add(2);49 System.out.println(arrayList.hashCode());//hashcode是对所有元素计算的到的。
50 Object []obj = coll.toArray();//集合变成数组
51 for (int i = 0; i < obj.length; i++) {52 System.out.println(obj[i]);53 }54 int[] a = {1,2,3};55 List ints = Arrays.asList(a);//数组变成集合
56 Iterator iterator =ints.iterator();57 while(iterator.hasNext()){58 System.out.println(iterator.next());59 }60 for(Object ob:coll){61 System.out.println(ob);62 }63 }64 //ArrayList:List的主要实现类
65 /*
66 * List中相对于Collection,新增加的方法67 * void add(int index, Object ele):在指定的索引位置index添加元素ele68 boolean addAll(int index, Collection eles)69 Object get(int index):获取指定索引的元素70 Object remove(int index):删除指定索引位置的元素71 Object set(int index, Object ele):设置指定索引位置的元素为ele72 int indexOf(Object obj):返回obj在集合中首次出现的位置。没有的话,返回-173 int lastIndexOf(Object obj):返回obj在集合中最后一次出现的位置.没有的话,返回-174 List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex结束的左闭右开一个子list75
76 List常用的方法:增(add(Object obj)) 删(remove) 改(set(int index,Object obj))77 查(get(int index)) 插(add(int index, Object ele)) 长度(size())78 */
79 @Test80 public voidtestArrayList(){81 ArrayList ints = newArrayList();82 ints.add(1);83 ints.add("a");84 Collection arrayList = newArrayList();85 arrayList.add("a");86 arrayList.add(1);87 System.out.println(arrayList.equals(ints));//判断相等不仅看元素,还要看顺序,
88 System.out.println(arrayList.hashCode());//一般hashcode除了要看内容,还要看顺序,因此若hashcode不相等,equals一般也不想等,互等价
89 System.out.println(ints.hashCode());90 ints.addAll(0,arrayList);91 System.out.println(ints);92 System.out.println(ints.get(0));93 System.out.println(ints.remove(0));//删除指定位置的元素
94 System.out.println(ints.indexOf("a"));//首次出现的位置,
95 System.out.println(ints.lastIndexOf("a"));//最后一次出现的位置
96 System.out.println(ints.subList(0,2));//返回左闭右开的区间的内容
97 System.out.println(ints.set(0,"b"));//指定位置修改
98 System.out.println(ints);99
100 }101
102 }
3.2 set接口
set集合中的元素或对象(主要是自己的实现类)要重写equals方法,因为equals方法是判断两个对象相等的条件,不重写可能导致相等的对象无法判断相等,
还要重写hashcode方法,否则会导致所有的对象的hashcode的值都相等,且只能输出一个对象的值。
linkedhashset要维护指针,所以插入的效率要低一些,但是频繁遍历的效果要好于hashset
要求是同一个类的才能添加到同一个treeset,才能按照统一的标准进行遍历。
1 packageSet;2
3 importorg.junit.Test;4
5 import java.util.*;6
7 public classSet {8 @Test9 public void test(){//测试hashset
10 HashSet hashSet = newHashSet();11 hashSet.add(123);12 hashSet.add(222);13 hashSet.add("BB");14 System.out.println(hashSet);//存储无顺序,输出也无顺序。
15 work work1 = new work("ll",10);16 work work2 = new work("ll",10);17 hashSet.add(work1);18 hashSet.add(work2);19 System.out.println(work1.hashCode());20 System.out.println(work2.hashCode());21 System.out.println(hashSet);//对类对象,只有重写hashCode方法和equals方法后,生成的对象的hash值才可以相同,才能保证set集合的无重复性
22 }23 /*
24 * LinkedHashSet:使用链表维护了一个添加进集合中的顺序。导致当我们遍历LinkedHashSet集合25 * 元素时,是按照添加进去的顺序遍历的!26 *27 * LinkedHashSet插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能。28 */
29 @Test30 public void test2(){//测试LinkedHashSet()
31 LinkedHashSet linkedHashSet = newLinkedHashSet();32 linkedHashSet.add(1);33 linkedHashSet.add(2);34 linkedHashSet.add(null);35 Iterator iterator1 =linkedHashSet.iterator();36 while (iterator1.hasNext())//因为测试LinkedHashSet在hashset的基础上添加了链表,因此所有添加的元素连接起来,遍历有序,这是主要的不同
37 {38 System.out.println(iterator1.next());39 }40
41 }42 @Test//自然排序
43 public void test3(){//在people类里面重写
44 TreeSet set = newTreeSet();45 set.add(new work("liulei",16));46 set.add(new work("ww",12));47 set.add(new work("cc",13));48 for(Object str1:set){49 System.out.println(str1);50 }51
52 }53 @Test54 public void test4(){//因为只有相同类的两个实例才会比较大小,所以向 TreeSet 中添加的应该是同一个类的对象
55
56 Comparator com = new Comparator() {//定制排序
57 @Override58 public intcompare(Object o1, Object o2) {59 if(o1 instanceof work && o2 instanceofwork){60 work c1 =(work) o1;61 work c2 =(work) o2;62 int i = c1.getAge().compareTo(c2.getAge());//小于负值大于正值
63 if(i==0){//相等,继续比较
64 returnc1.getName().compareTo(c2.getName());65 }66 returni;67 }68 return 0;69 }70 };71 TreeSet set = newTreeSet();72 set.add(new work("liulei",16));73 set.add(new work("ww",12));74 set.add(new work("cc",13));75 for(Object str1:set){76 System.out.println(str1);77 }78
79 }80
81 }
对于自然排序,people里面实验Comparable,重写compareTo方法
packageSet;public class Person implementsComparable{privateString name;privateInteger age;publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}publicInteger getAge() {returnage;
}public voidsetAge(Integer age) {this.age =age;
}publicPerson() {super();
}publicPerson(String name, Integer age) {super();this.name =name;this.age =age;
}
@OverridepublicString toString() {return "Person [name=" + name + ", age=" + age + "]";
}//static int init = 1000;
@Overridepublic int hashCode() {//return age.hashCode() + name.hashCode();û�����Ľ�׳�Ժá�
final int prime = 31;int result = 1;
result= prime * result + ((age == null) ? 0: age.hashCode());
result= prime * result + ((name == null) ? 0: name.hashCode());returnresult;//return init++;//����������
}
@Overridepublic booleanequals(Object obj) {if (this ==obj)return true;if (obj == null)return false;if (getClass() !=obj.getClass())return false;
Person other=(Person) obj;if (age == null) {if (other.age != null)return false;
}else if (!age.equals(other.age))return false;if (name == null) {if (other.name != null)return false;
}else if (!name.equals(other.name))return false;return true;
}//����TreeSet�����Person��Ķ���ʱ�����ݴ˷�����ȷ�������ĸ��������С�
@Overridepublic intcompareTo(Object o) {if(o instanceofPerson){
Person p=(Person)o;//return this.name.compareTo(p.name);//return -this.age.compareTo(p.age);
int i = this.age.compareTo(p.age);if(i == 0){return this.name.compareTo(p.name);
}else{returni;
}
}return 0;
}
}
View Code
自然排序
1 @Override2 public intcompareTo(Object o) {3 if(o instanceofPerson){4 Person p =(Person)o;5 //return this.name.compareTo(p.name);6 //return -this.age.compareTo(p.age);
7 int i = this.age.compareTo(p.age);8 if(i == 0){9 return this.name.compareTo(p.name);10 }else{11 returni;12 }13 }14 return 0;15 }
定制排序
Comparator com = new Comparator() {//定制排序
@Overridepublic intcompare(Object o1, Object o2) {if(o1 instanceof work && o2 instanceofwork){
work c1=(work) o1;
work c2=(work) o2;int i = c1.getAge().compareTo(c2.getAge());//小于负值大于正值
if(i==0){//相等,继续比较
returnc1.getName().compareTo(c2.getName());
}returni;
}return 0;
}
};
3.3.Queue
Queue接口与List、Set同一级别,都是继承了Collection接口。LinkedList实现了Queue接 口。Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法 了,而不能直接访问 LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用。BlockingQueue 继承了Queue接口。队列是一种先进先出的数据结构,元素在队列末尾添加,在队列头部删除。Queue接口扩展自Collection,并提供插入、提取、检验等操作。上图中,方法offer表示向队列添加一个元素,poll()与remove()方法都是移除队列头部的元素,两者的区别在于如果队列为空,那么poll()返回的是null,而remove()会抛出一个异常。方法element()与peek()主要是获取头部元素,不删除。接口Deque,是一个扩展自Queue的双端队列,它支持在两端插入和删除元素,因为LinkedList类实现了Deque接口,所以通常我们可以使用LinkedList来创建一个队列。PriorityQueue类实现了一个优先队列,优先队列中元素被赋予优先级,拥有高优先级的先被删除。
四:Map接口
3.1 hashmap
3.2 Linkedhashmap
3.3 Treemap
3.4 Hashtable
3.5 properties
1 @Test2 public void Test5() throwsIOException {3 Properties pros = newProperties();4 pros.load(new FileInputStream(new File("D:/config.txt")));5 String user = pros.getProperty("user");6 System.out.println(user);7 }
五:Collections工具类
1 packagecom.atguigu.java;2
3 importjava.util.ArrayList;4 importjava.util.Arrays;5 importjava.util.Collections;6 importjava.util.List;7
8 importorg.junit.Test;9
10 /*
11 * 操作Collection以及Map的工具类:Collections12 *13 * 面试题:区分Collection与Collections14 *15 */
16 public classTestCollections {17 /*
18 * Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素19 Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素20 Object min(Collection)21 Object min(Collection,Comparator)22 int frequency(Collection,Object):返回指定集合中指定元素的出现次数23 void copy(List dest,List src):将src中的内容复制到dest中24 boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值25
26 */
27 @Test28 public voidtestCollections2(){29 List list = newArrayList();30 list.add(123);31 list.add(456);32 list.add(12);33 list.add(78);34 list.add(456);35 Object obj =Collections.max(list);36 System.out.println(obj);37 int count = Collections.frequency(list, 4567);38 System.out.println(count);39 //实现List的复制40 //List list1 = new ArrayList();//错误的实现方式
41 List list1 = Arrays.asList(newObject[list.size()]);42 Collections.copy(list1, list);43 System.out.println(list1);44 //通过如下的方法保证list的线程安全性。
45 List list2 =Collections.synchronizedList(list);46 System.out.println(list2);47 }48 /*
49 * reverse(List):反转 List 中元素的顺序50 shuffle(List):对 List 集合元素进行随机排序51 sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序52 sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序53 swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换54
55 */
56 @Test57 public voidtestCollections1(){58 List list = newArrayList();59 list.add(123);60 list.add(456);61 list.add(12);62 list.add(78);63 System.out.println(list);64 Collections.reverse(list);65 System.out.println(list);66 Collections.shuffle(list);67 System.out.println(list);68 Collections.sort(list);69 System.out.println(list);70 Collections.swap(list, 0, 2);71 System.out.println(list);72 }73 }