黑马程序员——集合框架
-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
1.为什么出现集合类?
面向对象语言对事物的体现都是以对象的形式存在,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。
数组和集合类同是容器,有何不同?
数组可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。
2.集合类的特点
集合只用于存储对象,集合长度是可变,集合可以存粗不同类型的对象。
集合框架
集合框架的共性方法
1.添加元素
add(Object obj);
2.删除元素
remove(Object obj)
3.获取集合长度
size();
1.add方法的参数类型是Object.以便于接受任意对象
2.集合中存储的都是对象的引用(地址)
一、List
什么是迭代器?
就是集合的取出元素的方式
取出方式定义在集合内部,这样的取出方式可以直接访问集合内容的元素
那么取出方式就被定义成了内部类
而每一个容器的数据结构不同,所以取出的动作细节也不一样。
但是都有共性内容判断和取出。那么可以将共性抽取
那么这些内部类都符合一个规则。该规则是Iterator.
如何获取集合的取出对象呢?
通过一个对外提供的方法。iterator()
class t1{
public static void main(String[] args){
method_get();
}
public static void method_get(){
//创建一个集合容器,使用Collection借口子类,ArrayList
ArrayList al=new ArrayList();
al.add("java1");
al.add("java2");
al.add("java3");
al.add("java4");
//原集合
show(al);
//获取个数,集合长度
show(al.size());
//删除元素
al.remove("java1");
//改变后集合
show(al);
Iterator it=al.iterator();//获取迭代器,用于取出集合中的元素。
while(it.hasNext()){
show(it.next());
}
}
public static void method_1(){
ArrayList al1=new ArrayList();
al1.add("java1");
al1.add("java2");
al1.add("java3");
al1.add("java4");
ArrayList al2=new ArrayList();
al2.add("java1");
al2.add("java2");
al2.add("java5");
al2.add("java6");
al1.retainAll(al2);//去交集,al1中只会保留与al2相同的元素
al1.removeAll(al2);//去除al1中与al2相同的元素
}
public static void show(Object obj){
System.out.println(obj);
}
}
List:
特有方法。凡是可以操作角标的方法都是该体系特有的方法
增:
add(index,element);
addAll(index,Collection);
删:
remove(index);
改:
set(index,element);
查
get(index);
subList(from, to);
listIterator();
List集合特有的迭代器,ListIterator是Iterator的子接口
在迭代时,不可以通过集合对象的方法操作集合中的元素。
因为会发生异常。
所以,在迭代时,只能用迭代器的方法操作元素,可是Iterator的方法是有限的,
只能对元素进行判断,取出,删除的操作,
如果想要其他的操作,如添加,修改,就需要使用其子接口,ListIterator.
该接口只能通过List集合ListIterator的方法获取
List:元素是有序的,元素可以重复,因为该集合体系有索引
ArrayList:(线程不同步)底层的数据结构使用的是数组结构。特点:查询速度很快,但是增删稍慢
LinkedList:底层使用的是链表数据结构。特点:增删速度很快,查询稍慢
Vector:(线程同步)底层的数据结构使用的是数组结构,被ArrayList替代了。
*/
public static void method_get(){
//创建一个集合容器,使用Collection借口子类,ArrayList
ArrayList al=new ArrayList();
al.add("java1");
al.add("java2");
al.add("java3");
al.add("java4");
//指定位置加元素
al.add(1,"java");
//修改元素
al.set(0,"java01");
//判断元素是否存在
show(al.contains("java2"));
//通过角标获取元素
al.get(1);
//获取所有元素
for(int x=0;x<al.size();x++){
System.out.println(al.get(x));
}
ListIterator li=al.ListIterator();
while(li.hasNext()){
Object obj=li.next();
if(obj.equals("java2")){
li.add("java00");
}
}
/* //在迭代过程中,准备添加或者删除元素。
Iterator it=al.iterator();
while(it.hasNext()){
show(it.next());
Object obj=it.next();
if(obj.equals("java2"))
//al.add("java8");//不能用
show(obj);
}*/
/*
LinkedList:特有方法
addFirst();
addLast();
//获取元素,但不删除元素
getFirst();
getLast();
//获取元素,并删除元素,如果集合中没有元素,会抛出异常
removeFirst();
removeLast();
在JDK1.6出现了替代方法
offerFirst();
offerLast();
peekFirst();
peekLast();
//获取元素,并删除元素,如果集合中没有元素,会返回null
pollFirst();
pollLast();
*/
public static void method_get1(){
//创建一个集合容器,使用Collection借口子类,ArrayList
LikedList link=new LinkedList();
link.addFirst("java1");
link.addFirst("java2");
link.addFirst("java3");
link.addFirst("java4");
}
List常见的子类对象:
ArrayList:底层的数据结构使用的是数组结构。特点:查询更改速度快,增删稍慢。线程不同步。可变长度数组:元素初始是10的元素空间,超过10空间,按原数组的50%增加空间,也就是变成15,new一个新的数组,将原始空间中的元素复制进来和新增加的元素添加到后面的空间中。
LinkedList:底层使用的是链表数据结构。特点:查询满,增删快。
Vector:底层是数组数据结构。特点:查询、增删满。线程同步。可变长度数组:元素初始是10的元素空间,超过10空间,按原数组的50%增加空间,也就是变成15,new一个新的数组,将原始空间中的元素复制进来和新增加的元素添加到后面的空间中。
Vector:枚举是Vector特有的取出方式,枚举和迭代器重复。枚举的名称和方法名称过长,被迭代器取代了。
二、Set
元素是无序(存入和取出的元素顺序不一定一致)的,元素不可以重复。
Set和Collection的功能是一致的。
Set常见子类对象
1.HashSet
HashSet:底层的数据结构是哈希表。线程不同步;
HashSet是如何保证元素的唯一性的呢?
是通过元素的两个方法,hashCode和equals来完成。
如果元素的HashCode值相同,才会判断equals是否为true。
如果元素的HashCode值不同,才会调用equals。
注意:对于判断元素是否存在,以及删除等操作,依赖方法是元素的hashCode和equals方法。
public class hashset {
public static void main(String[] args){
HashSet hs=new HashSet();
hs.add(new person("a1",20));
hs.add(new person("a2",23));
hs.add(new person("a3",22));
hs.add(new person("a4",24));
hs.add(new person("a4",24));
hs.add(new person("a1",20));
Iterator it=hs.iterator();
while(it.hasNext()){
Object obj=it.next();
person p=(person)obj;
System.out.println(p.getName()+"...."+p.getAge());
}
}
}
class person{
private String name;
private int age;
person(String name,int age){
this.name=name;
this.age=age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public int hashCode(){
System.out.println(name+"......code.......");
return name.hashCode()+age*9;
}
public boolean equals(Object obj){
if(!(obj instanceof person))
return false;
person p=(person)obj;
System.out.println(this.name+".equals.."+p.name);
return this.name.equals(p.name) && this.age==p.age;
}
}
2.TreeSet
TreeSet:可以对Set集合中的元素进行排序,
底层数据结构是二叉树
保证元素唯一性的依据:compareTo方法 return 0.
TreeSet排序的第一种方式,让元素自身具备比较性
元素需要实现Comparable接口,覆盖compareTo方法。
这种方式也称为元素的自然顺序,或者叫默认顺序。
TreeSet的第二种排序方式
当元素不具备比较性时,或者具备的比较性不是所需要的
这时就需要让集合自身具备比较性
在集合初始化时,就有了比较性
定义一个比较器,将比较器对象作为参数传递给Tre集合的构造函数。
当两种排序都存在时,以比较器为主。
/*public class SET {
public static void main(String[] args){
TreeSet ts=new TreeSet();
ts.add(new student("a2",23));
ts.add(new student("a1",22));
ts.add(new student("a3",24));
ts.add(new student("a4",22));
ts.add(new student("a4",22));
Iterator it=ts.iterator();
while(it.hasNext()){
Object obj=it.next();
student s=(student)obj;
System.out.println(s.getName()+"...."+s.getAge());
}
}
}
class student implements Comparable{
private String name;
private int age;
student(String name,int age){
this.name=name;
this.age=age;
}
public int compareTo(Object obj){//强制让学生具备比较性
if(!(obj instanceof student))
throw new RuntimeException("不是学生对象");
student s=(student)obj;
if(this.age>s.age)
return 1;
if(this.age==s.age)
return this.name.compareTo(s.name);
return -1;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
}*/
//方法二
public class SET {
public static void main(String[] args){
TreeSet ts=new TreeSet();
ts.add(new student("a2",23));
ts.add(new student("a1",22));
ts.add(new student("a3",24));
ts.add(new student("a4",22));
ts.add(new student("a4",22));
Iterator it=ts.iterator();
while(it.hasNext()){
Object obj=it.next();
student s=(student)obj;
System.out.println(s.getName()+"...."+s.getAge());
}
}
}
class student implements Comparable{
private String name;
private int age;
student(String name,int age){
this.name=name;
this.age=age;
}
public int compareTo(Object obj){//强制让学生具备比较性
if(!(obj instanceof student))
throw new RuntimeException("不是学生对象");
student s=(student)obj;
if(this.age>s.age)
return 1;
if(this.age==s.age)
return this.name.compareTo(s.name);
return -1;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
}
3.Map
Map集合:该集合储存键值对。一对一对往里存,而且要 保证键的唯一性。
1、添加
put(K key, V value);
putAll(Map<? extends k,? extends V> m)
2、删除
clear();
3、判断
containValue(Object value);
containKye(Object key);
isEmpty();
4、获取
get(Object key)
size();
values();
entrySet()
keySet()
Map
Hashtable:底层是哈希表数据结构,不允许使用null值和键,该集合线程同步
HashMap:底层是哈希表数据结构,允许使用null值和键。该集合线程不同步
TreeMap:底层是二叉树数据结构,线程不同步
和Set很像,Set底层就是用了Map集合
public class MAP {
public static void main(String[] args){
Map<String,String> map=new HashMap<String,String>();
map.put("1","a1");
map.put("2","a2");
map.put("3","a3");
System.out.println(map.containsKey("1"));
System.out.println(map.get("1"));
Collection<String> cl=map.values();
System.out.println(cl);
System.out.println(map);
//先获取map集合的所有键的Set集合,keySet();
Set<String> keySet=map.keySet();
//有了集合,就可以获取迭代器
Iterator<String> it=keySet.iterator();
while(it.hasNext()){
String s=it.next();
//有了键,就可以通过map集合get方法获取对应值
String t=map.get(s);
System.out.println(t);
}
//将map集合中的映射关系取出,存入到Set集合中
Set<Map.Entry<String, String>> entry=map.entrySet();
Iterator<Map.Entry<String, String>> it1=entry.iterator();
while(it1.hasNext()){
Map.Entry<String, String> m=it1.next();
String k=m.getKey();
String v=m.getValue();
System.out.println(k+"...."+v);
}
}
}
Map集合的取出方式
1、keySet;将map中所有的键存到Set集合。因为set具备迭代器
所以可以通过迭代方式取出所有的键,根据get方法。获取每一个键对应的值
entrySet;
Map集合的取出原理就是讲Map集合转成Set集合。再通过迭代取出
2、Set<Map.Entry<k,v>> entrySet:将map集合中的映射关系存入到set集合中
而这个关系的数据类型就是map.Entry。
map扩展知识
map集合被使用时因为具备映射关系