您的位置:首页 > 职场人生

黑马程序员——JAVA基础——集合---概述、Collection中共性方法、List、Map、工具类Collections和Arrays

2015-03-29 16:48 921 查看
-----------android培训java培训、java学习型技术博客、期待与您交流!------------

第一讲.概述

集合就是用来存放多个数据的,感觉数据结构这门课很大一部分讲的就是这个
集合和数组是不一样的,数组长度不可变、无法保存具有映射关系的数据(图中键值对的概念)等,Java集合类就灵活得多。
Java的集合大致分为Set、List、Map三种体系,Set代表无序、不可重复的集合;List代表有序、重复的集合;Map代表具有映射关系的集合。Java5以后又出现了Quene体系集合,代表队列。
Java集合的体系框架图如下:这里面涉及到继承关系、实现方式还有工具类(Collections)及相关比较方法(Comparator)。



第二讲.Collection接口和Iterator遍历器

集合的几大功能:增删改查,Collection接口里基本都有定义
集合一些共性的方法如下:注意集合中存放的是元素对象的引用;
//这里ArrayList和HashSet是Collection接口的典型实现类
Collection a = new ArrayList();
a.add("SunWuKong");//添加元素
a.add(6);//集合里不能存放基本类型的元素,但Java支持自动装箱
a.remove(6);//删除
a.size();//c集合里元素的个数
a.contains("SunWuKong"));//是否包含某个元素
System.out.println(a);//调用toString()方法打印集合元素
Collection b = new HashSet();
b.add("SunWuKong");
b.add("ZhuBaJie");
a.containsAll(b);//A集合是否包含B集合中的全部元素
b.retainAll(a);//B集合中只剩A集合也包含的元素,即A,B的交集
a.removeAll(b);//把A集合中与B集合相同的元素删除,即A-B
a.clear();//删除A集合中的所有元素

Iterator遍历集合元素,注意Iterator并不是把集合元素本身传给迭代变量,只是把集合元素的值复制一份传给迭代变量,所以修改迭代变量的值无法改变集合元素本身。利用foreach方法遍历集合元素也是如此。
//所谓迭代器Iterator,就是集合取出元素的方式所抽象出的接口
//设计方式:实际上Iterator被设计为Collection接口的内部接口,它统一了集合的取出方式
//Iterator接口里定义了三个方法:next(),hasNext(),remove()
Collection c = new ArrayList();
c.add("Java01");
c.add("Java02");
c.add("Java03");
c.add("Java04");
Iterator it = c.iterator();
while(it.hasNext()){
System.out.println(it.next());
//注意,使用迭代器对集合进行迭代访问时,不能通过集合的add()、remove()等方法改变集合元素。
//否则会引发java.util.Concurrent ModificationException并发修改异常
//只允许用Iterator的remove()方法删除上一次next()返回的元素。
it.remove();
}
System.out.println(c);


第三讲.List集合

元素是有序的,元素可重复,因为该集合体系有索引。
List中的共性方法
//由于有索引,List提供一些操作角标的共性方法
int index =2;
String element = "JavaTest";
List list = new ArrayList();
list.add("Java01");
list.add("Java02");
list.add("Java03");
list.add("Java04");
//list.add(index,elememt);//在索引处插入元素,addAll(index,Collection)同理
//remove(index);//删
//set(index,element);//改
//get(index);//查
//System.out.println(subList(2,3))//subList(from,to)截取子List,包含头不含尾
System.out.println(list);

List中特有的ListIterator列表迭代器
//List特有的ListInterator迭代器,在Iterator上添加了三个方法:
//hasPrevious()与Object previous()可以前向遍历,void add()在当前迭代位置添加元素
ListIterator it = list.listIterator();
while(it.hasNext()){
System.out.println(it.next());
it.add("---------华丽分割线-----------");
}
while(it.hasPrevious()){//前向遍历
System.out.println(it.previous());
//这里不能it.add(element)了,否则无限循环了。。
}

ArrayList:底层为数组数据结构,查找快、增删慢。默认的数组长度为10,如果超出了就延长50%(就是再new个更长点的数组把之前的元素copy过去)。
Vector:底层数组数据结构,Vector线程安全(ArrayList()线程不安全),Vector是JDk1.0就存在了(元老级),集合框架JDK1.2才出现。由于性能不好,被ArrayList替代了。Vector有个elements()返回Enumeration枚举,它被Iterator替代,但1.0的一些老类(如合并流)还在使用。
枚举Enumeraton其实和迭代Iterator是一样的,Iterator在之后的版本中替代了枚举,下面这段代码展示其用法:
Vector v = new Vector();
v.add("Element1");
v.add("Element2");
v.add("Element3");
Enumeration en = v.elements();//带element的都是Vector的特有方法
while(en.hasMoreElements)//由于名字过长,就被Iterator替代了
//虽然已经被替代了,但是由于像合并流SequenceInputStream也是1.0版本的,它用的是枚举,所以还是有必要了解的
System.out.println(en.nextElement());

LinkedList:底层为链表数据结构,查找慢、增删快,它的一些特有方法如下:
//LinkedListd的特有方法:
//addFirst(),addLast(),
//getFirst(),getLast(),
//removeFirst(),removeLast()
//上面这些方法(当然不包括add),当列表为空时都返回NoSuchElement异常
//后期JDK1.6出现了这些方法的升级版,失败时就返回null
//peek(),获取不删除, 还有peekFirst(),peekLast()
//poll(),获取并删除, 还有pollFirst(),pollLast()
//push(),压栈;pop(),出栈
//这些都是栈操作的一些叫法。。因为链表适合于实现堆栈(频繁增删嘛)。


第四讲.泛型

泛型是JDK5.0后引入的新概念, 避免了强制类型转换。就是写的时候可以定义一个形式上的类型,等到调用再时指定具体类型。具体的在下面的代码中就能见到,比较容易理解。
泛型限定:向上限定,? extends E:可以接收E和E的子类型。?表示通配符,在函数传参时候用到。例子:Collection<E>的
addAll(Collection<? extendsE>
c),代表它可以添加子类型组成的集合。

泛型限定:向下限定,? super E:可以接受E和E的福类型。TreeSet<E>的构造方法
TreeSet(Comparator<?
superE> comparator)
,代表只要为父类实现了比较器,其子类也能使用。[/code]

第五讲.Set集合

Set是无序的(存入和取出的顺序不一致),元素不能重复
Set的方法和Collection的方法是一致的,只是有元素不重复的限制。所有Set实现类都有自己的去重方法,保证元素唯一性。
HashSet:底层数据结构为哈希表,就是按照哈希值分区存放的表。它通过哈希值进行散列,期望令数据尽量均匀分散分布。取元素时就按照哈希值查表,所以较快。
Object中定义了int hashCode()方法计算哈希值,toStrint()方法返回的字符串就是"类名@哈希值"。HashSet就是通过hashCode()加boolean equals(Object obj)去重的,如果哈希值相同就去调用equals(),为true才说明两元素相同;如果元素哈希值就不同了,那么直接就认定不相同就不会比较equals了(做一下对比:ArrayList中的contains方法判断元素相同就只依赖equals了)。我们可以通过覆写hashCode和equals方法来定义自己的HashSet去重方法。(注:Object中的equals()方法通过return
this==obj方式判断相等。)
TreeSet:底层数据结构为二叉树,可以集合元素保序存放。当存入自定义对象时,一种是要声明其实现Comparable<T>接口并覆写int compareTo(T obj)方法,这种就叫做对象的自然顺序;另一种在new TreeSet时传入比较器接口Comparator<T>(需要实现一个int compare(T o1,T o2)的方法)实现类实例,可以做到强制按给定顺序排序。当然比较操作返回0就可以判断元素是否相等了,不过Java还是会再判断一下equals来保持程序的健壮性。
这里写了一个覆写各种去重相关函数的类Person
class Person implements Comparable<Person>//泛型的写法,Comparable就是一个泛型接口
{
private String name;
private int age;
boolean equals(Object obj){//注意参数为Object类型,没泛型的事!
if(!obj instanceof Person)
return false;
Person p = (Person)obj;
return this.name==p.name&&this.age==p.age;
}
int hashCode(){
return name.hashCode()+age*19;//乘个素数,降低偶然相等可能性
}
int compareTo(Person p){
//按年龄排序
if(this.age!=p.age)
return this.age-p.age;
else//如果主要条件相同了就比较次要条件
return this.name.compareTo(p.name);
}
}

TreeSet小练习:按照字符串长度排序
//应用匿名内部类
TreeSet<String> set=new TreeSet<String>(new Comparator<String>(){
public int compare(String s1,String s2){
return s1.length()-s2.length();
}
});
set.add("hahahahaha");
set.add("ha");
set.add("hahaha");
set.add("haha");
set.add("hahahaha");
for (String item:set)
System.out.println(item);
}


第六讲.Map集合

Map集合存放键值对。Map与Collection同级的。Collection由Map实现。
Map的共性方法
//添加
put(K key,V value);putAll(Map<? extends K,? extends V> m);
//删除
clear();remove(Object key);
//判断
containsKey(Object key);containsValue(Object value);isEmpty();
//获取
get(Object key);size();
values() 返回此映射中包含的值的 Collection 视图。
//较重要的两个Set
entrySet()返回映射关系的Set,之后会提到
keySet()返回键组成的Set

通过keySet()方法遍历Map:
Map<String,String> map = new HashMap<String,String>();
map.put("孙悟空","五指山");
map.put("猪八戒","高老庄");
map.put("沙和尚","流沙河");
map.put("唐三藏","女儿国");
for(String item:map.keySet())
System.out.println(item+"::"+map.get(item));

Map中的内部类Map.Entry,代表了映射关系,通过entrySet()方法遍历Map:
//Map.Entry就是把Key和Value封装成一个类了
//Map和Set关系密切,从Java源代码看,Java是先实现了Map,然后通过包装一个所有value都为null的Map就实现了Set
for(Map.Entry<String,String> item:map.entrySet())
System.out.println(item.getKey()+"::"+item.getValue());

HashMap和HashTable,两者关系完全与ArrayList和Vector的关系相同。HashTable比较古老的类,线程安全,不允许空键空值。HashMap运行使用null作为key和value。它们底层通过哈希表实现,可以详见HashSet,不同的是Map里比较的是key。
TreeMap可以按照key排序,详见TreeSet,同样有实现Comparable接口和创建时传入Comparator实现类实例两者排序方式。
小练习:获取字符串中字母出现的次数
//获取字符串中字母出现的次数
String str = "saweasdfareaefasffewafaegare";
Map<Character,Integer> map = new HashMap<Character,Integer>();
for(Character ch:str.toCharArray())
if(map.containsKey(ch))
map.put(ch,map.get(ch)+1);
else
map.put(ch,1);
for(Character ch:map.keySet())
System.out.println(ch+"("+map.get(ch)+")");


第七讲.工具类Collections和Arrays

Collections专门用来操作集合的工具类,里面全是静态方法。充分地运用了泛型。
Collections.sort()方法:sort(List<T> list, Comparator<? super T> c) 根据指定比较器产生的顺序对指定列表进行排序。
Collections.synchronizedList()方法:public static <T> List<T> synchronizedList(List<T> list),返回同步列表。
还有max,binarySearch,fill:把集合中所有元素用指定值替换,repalceAll:老值替换为新值,reverse,reverseOrder:返回一个逆向比较器,等方法详见JDK。
Arrays专门用来操作数组
Arrays也有很多操作数组的便捷方法,像sort排序,toString()显示数组元素,asList()转化为列表(不能变长度,不能进行增删)
为了限定地元素的操作,需要把集合变为数组,不让对其进行增删。Collection提供toArray()方法把集合转变为数组。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐