集合体系
1、Collection:
集合框架的由来:因为每个容器对象的自身的数据结构不同,所以对它们进行单独的描述和对象封装,并不断的向上抽取共性内容,这样变形成了集合框架。
定义:集合就是一个容器、用来存储对象、长度可变。
理解:其实班级就是一个容器,班上的每一个学生都是单独封装了功能的对象,因为班级中的人数由于有人请假每天都再变化,所以长度是可变的,
常见方法:
1、增加:
add();增加一个元素
addAll();增加一部分元素。
2、删除:
Remove();删除一个元素,会返回boolean类型,其实用到是equals方法,所以判断是否有符合要求的元素。如果删除成功会改变集合的长度。下面同理。
removeAll();删除全部
Clrea();清空容器
总结:在这里要尤其注意,面试题中经常考到。
3、判断:
Contains();是否包含,也就说要所有的都包含在其中才算包含,否则不算包含。
isEmpty();集合是否为空
Size();集合长度。
4、取:
retainAll();取交集。
理解总结:
班级就是一个容器,班级中进来一位新生就是Add()添加一个元素,来了一堆同学就是addAll,班上出去一个学生就是remove删除一个,出去一部分就是removeAll删除一部分,班级是不是有人,isEmpty,班上是否包含张三contains,班上有多少人size。班上是否包含隔壁班的同学retainAll.去交集。
集合使用细节:
1、直接存储基本数据类型值也是可以的,因为JDK1.5后有自动装箱,会将基本数据类型转成对象,JDK1.4绝对不行。Eg:coll.add(3)
2、集合对象中存储的其实是对象的元素的引用。
3、Add的参数是Object类型,可以接收所有的类型的对象,会出现向上转型,取出元素时类型还是Object不能使用具体对象的特有内容,想要使用特有内容向下转型。Eg:Object obj="obj";想要取出访问子类的特有方法,向下转型,String s=(String)it.next();sop(s.length());
|--List:有序列表(存取顺序是一致的)因为该子体系元素中有索引或角标,可以存储重复的元素。
常用方法:
//添加:
List.add(1,"abc7");//[abc1,abc7,abc2,abc3]在角标1位置往后顺延。
//删除
Object obj=list.remove(2);//删除指定索引上的元素,根据角标删除会返回来被删对象
Sop(obj);//obj:abc2 [abc1,abc7,abc3]
//获取:获取指定角标上的元素并返回,这也是和remove的区别。
Object obj=list.get(1);
Sop(obj);//obj:abc1 [abc1,abc7,abc3]
//获取元素的索引,如果元素存在返回索引,不存在返回-1,依次还可以判断元素是否存在。
Int index=list.indexOf("abc1");
Sop(index);//index=1
//获取指定的子列表sublist(fromIndex,toindex)包含头不包含尾
List=list.sublist(1,2);//[abc1]
//修改:
Object obj=list.set(1,"haha");
Sop(obj);//[abc1,haha,abc3]
记住:只有list集合支持增删改查。
|--ArrayList:低层是数组数据结构,不同步,查询快,增删慢,
|--LinkedList:低层是链表数据结构,不同步,查询慢,增删较快。
|--Vector:低层是数组数据结构,同步,安全效率低,还有其特有方法枚举。由于名称过长被iterator取代。
总结:掌握这些集合的方法,它们的方法和list集合的方法很相似,重点掌握各种集合的特点,尤其是前两个子类的低层数据结构。
|--Set
无序、不能存储重复的元素、方法个collection集合的方法一致。
|--HashSet
低层是哈希表数据结构,无序,能保证元素的唯一性,是根据元素的两个方法来保证元素的唯一性的,hasCode和equals方法。只有当hasCode算出的哈希值相同的情况下才去判断equals方法是否为true.如果为真说明两个元素相同,不存储,所以往hashSet集合中存储自定义对象时要覆写hasCode方法和equals方法,
重点掌握上述保证唯一性的方法以及哈希表内存原理实现。
|--linkedHashSet
以元素的插入顺序来维护集合的连接表,允许以插入的顺序的集合中迭代的
怎么去理解?
HashSet<String> hs=new HashSet<String>();
hs.add("B");
hs.add("A");
hs.add("D");
hs.add("E");
hs.add("C");
hs.add("F");
System.out.println("HashSet:"+hs);
LinkedHashSet<String> lhs=new LinkedHashSet<String>();
lhs.add("B");
lhs.add("A");
lhs.add("D");
lhs.add("E");
lhs.add("C");
lhs.add("F");
System.out.println("LinkedHashSet:"+lhs);
TreeSet<String> ts=new TreeSet<String>();
ts.add("B");
ts.add("A");
ts.add("D");
ts.add("E");
ts.add("C");
ts.add("F");
System.out.println("TreeSet:"+ts);
结果:
HashSet:[D, E, F, A, B, C]
LinkedHashSet:[B, A, D, E, C, F]
TreeSet:[A, B, C, D, E, F]
从结果可以知道对于LinkedHashSet集合可以保证元素按照添加的顺序取出元素,而TreeSet集合可以对集合中的元素进行自然排序。
|--TreeSet
用于给set集合中元素按照指定的顺序进行排序,低层是二叉树结构,线程是不同步的,
两种排序方式:
1、让元素自身具备比较功能,就是强制让元素去实现comparable接口,覆盖compareTo方法。这时元素具备的自然排序。可是如果元素自身不具备比较的功能,获取具备的比较功能不是所需要的。这时该排序方式就不能用了。
2、让集合自身具备比较功能,需要定义比较器,其实就是将实现了Comparator接口的子类对象作为参数传递给TreeSet集合的构造函数,让treeSet集合一创建就具备了比较功能。该子类必须要覆盖compare方法。
掌握二叉树数据结构的特点:不明白?
2、Map:
特点:
1、它是集合框架中的顶层
2、它存储的是键值对。
3、Map集合中必须保证键的唯一性。
4、如果存储键值对时,键重复,新值覆盖旧值。其实存储的就是一种映射关系。
常见方法:
增加:
Put();
putAll();
删除:
Clrea();
Remove(key);
判断:
containKey();
containValue();
获取:
get(Object key);
Size();
Values();
entrySet();将map集合中的映射关系
map.Entry其实Entry也是一个接口,它是map接口中的一个内部接口。
Interface Map{
public static interface Entry{
public abstract Object getKey();
public abstract Object getValue();
}
}
keySet();将map中所有的键都存入了set集合,因为set具备迭代器,所以可以迭代方式取出所有的键,在根据get方法获取每一个键对应的值。
Map集合的取出原理:将map集合转成set集合,在通过迭代器取出.
|--HashMap:低层是哈希表数据结构,该集合是不同步的,允许使用null键和null值。JDK1.2效率高
|--LinkedHashMap:保证按照插入的顺序进行取出。
|--TreeMap:低层是二叉树数据结构,线程不同步,可以用于给Map集合中的键进行排序。
3、Iterator
迭代器原理:其实就collection这个集合公共取出方式,因为每个容器的自身的数据结构不同,它们的取出方式也是不同的,要根据每个容器的特点来定义特定的取出方式,而取出方式直接在访问容器中的元素,所以将取出方式定义在容器的内部,是一个内部类,而对外提供访问接口。这样可以通过接口访问任何的collection容器中的元素,所以它的出现降低了耦合性,我们只用面对Iterator接口,和使用接口就可以了。
理解:抓布娃娃游戏机。
|--ListIterator
列表迭代器:要想在迭代过程中进行增删操作Iterator是不可以的,它只有删除动作,所以可以使用其子接口listIterator,是list集合特有的取出方式,它包包含了增删改查的方法。
4、Collections和Collection的区别:(面试题)
1、java.util.Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
2、java.util.Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。
Java代码
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.List;
- public class TestCollections {
- public static void main(String args[]) {
- //注意List是实现Collection接口的
- List list = new ArrayList();
- double array[] = { 112, 111, 23, 456, 231 };
- for (int i = 0; i < array.length; i++) {
- list.add(new Double(array[i]));
- }
- Collections.sort(list);
- for (int i = 0; i < array.length; i++) {
- System.out.println(list.get(i));
- }
- // 结果:23.0 111.0 112.0 231.0 456.0
- }
20.}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TestCollections {
public static void main(String args[]) {
//注意List是实现Collection接口的
List list = new ArrayList();
double array[] = { 112, 111, 23, 456, 231 };
for (int i = 0; i < array.length; i++) {
list.add(new Double(array[i]));
}
Collections.sort(list);
for (int i = 0; i < array.length; i++) {
System.out.println(list.get(i));
}
// 结果:23.0 111.0 112.0 231.0 456.0
}
}
package com.pers.Test; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.Map.Entry; public class ArrayTest { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub /*// Integer[] a = {1,2,3,4}; int [] a = {1,2,3,4}; List list = Arrays.asList(a); System.out.println("个数"+ list.size());*/ /* String[] arr={"ahas","abd","haha","xixi"}; List list=Arrays.asList(arr);//数组转集合 // System.out.println(arr[0]); for(String s : arr){ System.out.println(s); } System.out.println(list.contains("haha")); System.out.println(list.indexOf("xixi"));*/ //因为数组长度是固定的,这里尽管改造成了集合,但是还使用低层的数组,不能做改变数组长度的操作,也就说增删不能操作 // list.add("xx");//java.lang.UnsupportedOperationException /* * 集合转数组 */ /* List<String> coll= new ArrayList<String>(); coll.add("abc"); coll.add("nba"); coll.add("xixi"); String[] arr=coll.toArray(new String[2]); System.out.println(Arrays.toString(arr));*/ /* * 在Map集合中 values():方法是获取集合中的所有的值----没有键,没有对应关系, KeySet(): 将Map中所有的键存入到set集合中。因为set具备迭代器。所有可以迭代方式取出所有的键,再根据get方法 获取每一个键对应的值。 keySet():迭代后只能通过get()取key entrySet(): Set<Map.Entry<K,V>> entrySet() //返回此映射中包含的映射关系的 Set视图 Map.Entry表示映射关系。entrySet():迭代后可以e.getKey(),e.getValue()取key和value。返回的是Entry接口 */ Map<Integer,String> map = new HashMap<Integer,String>(); map.put(0,"haha"); map.put(1,"qq"); map.put(2,"jjha"); //方式1 Collection<String> col = map.values(); System.out.println(col); //[haha, qq, jjha] //方式2 Iterator<Integer> it = map.keySet() //先获取map集合的所有键的Set集合 .iterator(); //有了Set集合,就可以获取其迭代器 while(it.hasNext()){ Integer key = it.next(); String value = map.get(key);////有了键可以通过map集合的get方法获取其对应的值。 System.out.println("key: "+key+"-->value: "+value);//获得key和value值 } //方式3 for(Integer key : map.keySet()){ System.out.println(map.get(key));//局限性 只能获取值 } //方式4--通过entrySet()方法将map集合中的映射关系取出 for(Map.Entry<Integer, String> m : map.entrySet()){ System.out.println("key="+m.getKey()+",value="+m.getValue()); } /* * 说明:keySet()的速度比entrySet()慢了很多,也就是keySet方式遍历Map的性能不如entrySet性能好 为了提高性能,以后多考虑用entrySet()方式来进行遍历 */ } }