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

黑马程序员-----集合类

2015-08-20 16:38 543 查看
——- android培训java培训、期待与您交流! ———-

一、Collection接口

1、 集合类的特点

集合只用于存储对象;长度是可变的;可以存储不同类型的对象(不可以存储基本数据类型值)

2、 集合类与数组的区别:

数组虽然可以存储对象,但长度是固定的,数组中可以存储基本数据类型;

集合类的长度是可变的,只能存储对象,不能存储基本数据类型。

3、 集合框架:

Collection(接口)
|-----List:有序的,元素可重复(有索引)
|---ArrayList
|---LinkedList
|---Vector(被ArrayList取代了)
|-----Set:无序的,元素不可重复
|---TreeSet
|---HashSet


4、 Collection的常见操作方法:(所有容器的共性方法)

A.  添加
Boolean  add (Object obj)
Boolean  addAll (Collection coll)
B.  删除
Boolean  remove(Object obj)
Boolean  removeAll (Collection coll):将相同的元素去除
Void clear()
C.  判断
Boolean  contains(Object obj)
Boolean  containsAll (Collection coll)
Boolean  isEmpty()
D.  获取
Int  size()
Iterator  iterator();
E.  其他
Boolean retainAll(Collection coll):取交集
Object[]  toArray():将集合转成数组


、List接口(除了继承了collection接口中的方法外,凡是操作角标的方法都是该体系特有的方法)

1、添加
add(index,element)
addAll(index,collection)
1、  删除
remove(index)
2、  修改
set(index,element)
3、  查找
get(index)
subList(from,to):包含头,不包含尾
listIterator():List接口特有的迭代器,列表迭代器


注意:List集合除了可以用listIterator(列表迭代器)来获取元素外,还可以用角标来获取元素。代码体现如下:

for(int x=0; x<list.size(); x++){
sop("get:"+list.get(x));
}


A. LinkedList容器:(底层是链表结构,特点是:增删速度很快)

LinkedList:特有方法。

a)  addFirst();
b)  addLast();
c)  在jdk1.6以后。
d)  offerFirst();
e)  offerLast();
f)  getFirst():获取链表中的第一个元素。如果链表为空,抛出NoSuchElementException;
g)  getLast();
h)  在jdk1.6以后。
i)  peekFirst();获取链表中的第一个元素。如果链表为空,返回null。
j)  peekLast();
k)  removeFirst():获取链表中的第一个元素,但是会删除链表中的第一个元素。如果链表为空,抛出NoSuchElementException
l)  removeLast();
m)  在jdk1.6以后。
n)  pollFirst();获取链表中的第一个元素,但是会删除链表中的第一个元素。如果链表为空,返回null。
o)  pollLast();


需求:使用LinkedList模拟一个堆栈或队列的数据结构(堆栈:先进后出;队列:先进先出;结合LinkedList里的addFirst()、addLast()、removeFirst()、removeLast()等方法来做)

代码如下:

package com.shan;
import java.util.*;

public class Dmeo5 {
public static void main(String[] args) {

DuiZhan  dl=new DuiZhan();
dl.myAdd("java01");
dl.myAdd("java02");
dl.myAdd("java03");
dl.myAdd("java04");
dl.myAdd("java05");

while(!dl.isNull())
{
System.out.println(dl.myGet());
}

}

}
class DuiZhan
{
private LinkedList<Object> link;
DuiZhan()
{
link=new LinkedList<Object>();
}
public void myAdd(Object obj)
{
link.addFirst(obj);
}
public Object myGet()
{
return link.removeFirst();
}
public boolean isNull()
{
return link.isEmpty();
}
}


B. ArrayList容器:(底层是数组结构,特点是:查询速度快)

需求:去除ArrayList集合中的重复元素

代码如下:

package com.shan;
import java.util.*;

public class Demo4 {

public static void main(String[] args)
{

ArrayList<String> al=new ArrayList<String>();
al.add("java01");
al.add("java02");
al.add("java02");
al.add("java01");
al=method(al);
System.out.println(al);
}

public static ArrayList<String> method(ArrayList<String> al)
{
ArrayList<String> al1=new ArrayList<String>();
Iterator<String> it=al.iterator();
while(it.hasNext())
{
String obj=it.next();
if(!al1.contains(obj))
{
al1.add( obj);
}
}
return al1;
}

}


C. Vector容器:(底层是数组结构,特点是:线程同步,增删查询速度都很慢)

枚举就是Vector中的特有的取出方法,枚举和迭代器的功能是一样的,因为枚举的名字过长,所以被迭代器取代了。

三、Set接口(Set集合中的方法与collection接口中的方法是一致的,没有额外的特殊方法)

A.HashSet容器:(底层是哈希表结构,特点是:线程非同步,没有重复元素,只需保证元素唯一性即可)

保证元素唯一性的原理:判断元素的hashCode值是否相同,如果相同,还会继续判断元素的equals方法是否为true

需求:用HashSet集合自定义一个学生类。

代码如下:

package com.shan;

import java.util.*;
public class Demo3 {

public static void main(String[] args)
{
HashSet<Student> hs=new HashSet<Student>();
hs.add(new Student("lisi01",21));
hs.add(new Student("lisi04",24));
hs.add(new Student("lisi02",22));
hs.add(new Student("lisi03",23));
hs.add(new Student("lisi04",24));
hs.add(new Student("lisi03",23));
Iterator<Student> it=hs.iterator();
while(it.hasNext())
{
System.out.println(it.next());

}

}

}
class Student
{
private String name;
private int age;
Student(String name,int age)
{
this.name=name;
this.age=age;
}
public void setName(String name)
{
this.name=name;
}
public void setAge(int age)
{
this.age=age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public String toString()
{
return name+"....."+age;

}
public int hashCode()
{
return age*name.hashCode();

}
public boolean equals(Object obj)
{
if(!(obj instanceof Student))
throw new RuntimeException();
Student p=(Student)obj;
return this.name.equals(p.name)&&this.age==p.age;
}

}


B.TreeSet容器:(底层是二叉树结构,特点是:没有重复元素,但可以对Set集合中的元素进行默认自然排序)

注意:TreeSet判断元素唯一性的方式:就是根据比较方法的返回结果是否是0,是0,就是相同元素,不存。

TreeSet排序的第一种方式:适应于元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。

TreeSet排序的第二种方式:适应于当元素自身不具备比较性时或具备的比较性不是所需要的,这时就需要让集合自身剧本比较性。即定义一个类,实现Comparator接口,并覆盖compare方法;定义比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。

举例说明:

(第一种方式:元素自身具备比较性)按年龄进行排序,若年龄相等,再按名字进行排序

package com.shan;

import java.util.Iterator;
import java.util.TreeSet;

public class Demo6 {

public static void main(String[] args) {
TreeSet<String> ts=new TreeSet<String>();
ts.add(new Student("zxx",18));
ts.add(new Student("abc",23));
ts.add(new Student("zah",21));
ts.add(new Student("xmh",19));

Iterator<String> it=ts.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}

}

}
class Student implements Comparable
{
private String name;
private int age;
Student(String name,int age)
{
this.name=name;
this.age=age;
}
public String toString()
{
return "age:"+age+"name:"+name;
}

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 void setName()
{
this.name=name;
}
public String getName()
{
return name;
}
public void setAge()
{
this.age=age;
}
public int getAge()
{
return age;
}
}


(第二种方式:元素自身不具备比较性)将上面的例子按名字进行排序。

class MyCompare implements Comparator
{
public int compare(Object obj1,Object obj2)
{
Student s1=(Student)obj1;
Student s2=(Student)obj2;
int num=s1.getName().compareTo(s2.getName());
if(num==0)
{
if(s1.getAge()>s2.getAge())
return 1;
if(s1.getAge()==s2.getAge())
return 0;
return -1;

}
return 0;

}
}


要想功能实现,只需要在上面一个例子中添加这段代码,同时将主函数中的
TreeSet<String> ts=new TreeSet<String>();这句话改为TreeSet<String> ts=new TreeSet<String>(new MyCompare());
即可。

四、Map接口

1、框架概述:

Map
|----Hashtable:底层是哈希表,该集合是同步的,不可以存入null键null值
|----HashMap:底层是哈希表,该集合是不同步的,允许使用null键null值
|----TreeMap:底层是二叉树,该集合是不同步的,可以用于给Map集合中的键进行排序。


2、Map接口定义了存储键/值对的方法,Map中不能有重复的键,Map实现类中存储的映射对都是通过“键“来唯一的标识的。

3、Map实现类的内部,都是用Set来存放映射对的“键“的,所以存入Map中的映射对的”键“对应的类必须重写equals方法和hashcode方法。(一般都用String对象作为Map的键)

4、常用方法:

1)、添加
value put(key,value):返回前一个和key关联的值,如果没有返回null。
value putAll(Map<? extends K,? extends V> m)
2)、删除
void clear():清空map集合。
value remove(Object key):根据指定的key删除这个键值对。
3)、判断
boolean containsKey(key);
boolean containsValue(value);
boolean isEmpty();
4)、获取
value get(key):通过键获取值,如果没有该键返回null。
当然可以通过返回null,来判断是否包含指定键。
int size():获取键值对个数。
values():获取Map集合中所有的值。
Set<Map.Entry<K,V>> entrySet():返回此映射中包含的映射关系
Set<K> keyset():返回此映射中包含的键


5、注意:

添加元素时,如果出现添加相同的键,那么后添加的值会覆盖原有键对应的值,并且put方法返回的是被覆盖的值,put方法返回值类型为Value

6、 取出方式一:

Set keyset()方法:将map中所有的键存入到Set集合,因为Set具备迭代器,所以可以用迭代方式取出所有的键,再根据get方法,获得每一个键对应的值。

package com.shan;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class Demo6 {

public static void main(String[] args) {
Map<String,String>  map=new HashMap<String,String>();
map.put("02", "shan02");
map.put("03", "shan03");
map.put("01", "shan01");
map.put("04", "shan04");
Set<String> keySet=map.keySet();
Iterator<String> it=keySet.iterator();
while(it.hasNext())
{
String key=it.next();
String value=map.get(key);
System.out.println("key="+key+"..."+"value="+value);
}

}

}


7、 取出方式二:

Set

Set<Map.Entry<String, String>> entrySet=map.entrySet();
Iterator<Map.Entry<String, String>> it=entrySet.iterator();
while(it.hasNext())
{
Map.Entry<String, String> me=it.next();
String key=me.getKey();
String value=me.getValue();
System.out.println("key="+key+"..."+"value="+value);
}


8、 HashMap容器:

用HashMap容器去自定义一个类时,最好在类中把功能写全。功能有:hashCode方法、equals方法,实现Comparable接口并重写compareTo()方法等

9、 TreeMap容器

只有TreeSet和TreeMap才可以使用排序的第二种方法,即比较器。(实现Comparator接口并重写compare()方法)

TreeMap类是根据其键的自然顺序进行排序的,或者是根据创建TreeMap对象时提供的比较器实例(实现Comparator接口的类的实例)进行排序的。

package com.shan;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/**练习:“sdfgzxcvasdfxcvdf”获取该字符串中的字母出现的次数
* 希望打印结果:a(1)c(2)....
*
* 思路:1、将字符串转换成字符数组,因为要对每一个字符进行操作
*     2、定义一个TreeMap集合,因为打印的结果有顺序
*     3、遍历字符数组,将每一个字符作为键查Map集合,如果返回null,则将这个字母和1存入集合中
*       如果返回不是null,说明该字母在集合中已经存在,并且有相应的次数,那么就将这个次数自增1后,将该个字母和自增后的次数存入集合中
*     4、将Map集合中的数据变成指定的字符串形式返回
*
* @author ling
*
*/
public class Demo7 {

public static void main(String[] args) {
String str="sdfgzxcvasdfxcvdf";
String s=charCount(str);
System.out.println(s);

}
public static String charCount(String str)
{
char[] ch=str.toCharArray();
TreeMap<Character,Integer>  tm=new TreeMap<Character,Integer>();
int count=0;
for(int x=0;x<ch.length;x++)
{
if(!(ch[x]>='a'&&ch[x]<='z'||ch[x]>='A'&&ch[x]<='Z'))
continue;
Integer value=tm.get(ch[x]);
if(value!=null)
count=value;
count++;
tm.put(ch[x], count);
}

StringBuilder sb=new StringBuilder();
Set<Map.Entry<Character,Integer>> entrySet=tm.entrySet();
Iterator<Map.Entry<Character,Integer>>  it=entrySet.iterator();
while(it.hasNext())
{
Map.Entry<Character,Integer>  me=it.next();
Character chs=me.getKey();
Integer  value=me.getValue();
sb.append(chs+"("+value+")");
}

return sb.toString();

}

}


——- android培训java培训、期待与您交流! ———-
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: