---------------------- android培训、java培训、期待与您交流! ----------------------
一、集合类:
1.为什么出现集合类?
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个
对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。
2.数组和集合类同是容器,有何不同?
数组虽然也可以存储对象 ,但长度是固定的,集合长度是可变的,
数组中可以存储基本数据类型,集合只能存储对象 。
3.集合类的特点:
集合只用于存储对象 ,集合长度是可变的,集合可以存储不同类型的对象
注:数据多了用对象封装,对象多了用集合封装 。
4.Collection是层次结构中的根接口,Collection表示一组对象 ,
这些对象也称为Collection的元素,一些Collection允许有重复的元素,
而另一些则不允许,一些Collection是有序的,而另一些则是无序的,
JDK不提供此接口的任何直接实现 ,它提供更具体的子接口(set,List)实现 ,
此接口通常用来传递collection,并在需要最大普遍性的地方操作这些collection.
5.常见操作:
1.)增加:
add();方法的参数是Object,以便于接收任意类型对象
2.)删除:
a1.clear();清空集合
a1.remove(对象);删除指定的对象
3.)判断:
a1.contains(对象);判断指定对象是否在集合中
a1.isEmpty();判断集合是否为空?当Size=0时,就为空
4.)取交集
a1.retainAll(a2);取交集,a1中只会保留和a2相同的对象(元素)
5.)元素的取出 :
什么是迭代器呢?
其实就是集合的取出元素的方法
Iterator it=a1.iterator();//获取迭代器,用于取出集合中的元素
it.hasNext();有下一个元素返回true,没有下一个元素返回flase
it.next();返回下一个元素。
for(Iterator it=a1.iterator();it.hasNext();)
{
sop(it.Next());
}
6.Collection:
1) Collection框架:(add,remove,contains clear iterator)
|---List:元素是有序的,元素可以重复,因为该集合体系有索引
|---ArrayList (不同步):底层的数据结构使用的是数组结构。特点:查询速度快,而增删速度稍慢
|---LinkedList:底层的数据结构使用的是链表数据结构,特点:增删的速度很快,查询稍慢
|---Vector(同步的) :底层是数组数据结构, 被ArrayList替代了,枚举就是Vector特有的取出方式
其实枚举和迭代是一样的
因为枚举的名称及方法的名称都过长,所以被迭代器取代了,枚举郁郁而终了
|---Set:元素无序,不可以重复
|---HashSet
|---TreeSet
2)Collection---->List:
add(E e);向列表的尾部添加指定的元素
add(int index,E element ):在列表的指定位置插入指定元素
addAll();添加指定Collection中的所有元素到此列表的结尾,顺序是指定Collection的迭代器返回这些元素的顺序
clear();从列表中移除所有元素
contains(Object o);如果列表包含指定的元素,则返回true
equals(Object o);比较指定对象与列表是否相等
get(int index);返回列表中指定位置的元素
indexOf(Object o);返回些列表中第一次出现的指定元素的索引,如果此列表不包含该元素,则返回-1;
isEmpty();如果列表不包含元素,则返回true;
iterator();返回按适当顺序在列表的元素上进行迭代的迭代器
lastIndexOf(Object o);返回此列表中最后出现的指定元素的索引 ,如果列表不包含些元素,则返回-1;
remove(int index);移除列表中指定位置的元素
remove(Object o);从此列表中移除第一次出现的指定元素(如果存在)
removeAll();从列表中移除指定collection中包含的其所有元素
retainAll();取子集
set(int index,E element);用指定元素替换列表中指定位置的元素
size();返回列表中的元素个数
List E subList(int fromIndex,int toIndex);返回列表中指定的部分视图
toArray();返回按适当顺序包含列表中的所有元素的数组
toArray(T[] a );返回按适当顺序包含列表中所有元素的数组,返回数组的运行时类型是指定数组的运行时类型
特有方法:凡是可以操作角标的方法都是该体系特有的方法
增
add(int index,element);
addAll(index,Collection);
删
remove(index);
改
set(index,element);
查
get(index);
subList(from ,to);
listIterator();
LinkedList:特有方法:
addFirst();
addLast();
getFirst();
getLast();
获取元素,但不删除元素,如果集合中没有元素,会出现NoSuchElementException
removeFirst();
removerLast();
获取元素,但是元素被删除,如果集合中没有元素,会出现NoSuchElementException
在JDK1.6出现了替代方法 :
offerFirst();
offerLast();
peekFirst();
peekLast();
获取元素,但是元素会被删除,如果集合中没有元素,会返回null
pollFirst();
pollLast();
获取元素,但是元素被删除,如果集合中没有元素,会返回null
Linkedlist练习:
使用LinkedList模拟一个堆栈或者队列数据结构
堆栈:先进后出,如同一个杯子
队列:先进先出,如同一个水管
import java.util.*;
class DuiLie
{
private LinkedList link;
DuiLie()
{
link=new LinkedList();
}
public void myAdd(Object obj)
{
link.addFirst(obj);
}
public Object myGet()
{
return link.removeLast();
}
public boolean isNull()
{
return link.isEmpty();
}
}
class LinkedListTest
{
public static void main(String[] args)
{
DuiLie d1=new DuiLie();
d1.myAdd("java01");
d1.myAdd("java02");
d1.myAdd("java03");
d1.myAdd("java04");
while(!d1.isNull())
{
System.out.println(d1.myGet());
}
}
}
ArrayList练习:
(1)去除ArrayList集合中的重复元素:
import java.util.*;
class ArrayListTest
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
ArrayList a1=new ArrayList();
a1.add("java01");
a1.add("java02");
a1.add("java01");
a1.add("java02");
a1.add("java01");
a1.add("java03");
sop(a1);
a1=singleElement(a1);
sop(a1);
}
public static ArrayList singleElement(ArrayList a1)
{
//定义一个临时容器
ArrayList newA1=new ArrayList();
Iterator it=a1.iterator();
while(a1.hasNext())
{
Object obj=a1.Next();
if(!newA1.contains(obj))
newA1.add(obj);
}
return newA1;
}
}
(2)将自定义对象作为元素存到ArrayList集合中,并去除重复元素
比如:存人对象 ,同姓名同年龄,视为同一个人,为重复元素:
思路 :
1.对人描述,将数据封装进人对象
2.定义容器,将人对象存入
3取出
List集合判断元素是否相同,依据的是元素的equals()方法
import java.util.*;
class Person()
{
private int age;
private String name;
Person(String name,int age)
{
this.name=name;
this.age=age;
}
public booean equals(Object obj)
{
if(!(obj instanceof Person))
return false;
Person p=(Person)obj;
return this.name.equals(p.name)&&this.age==p.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
class ArrayListTest2
{
public static void main(String[] args)
{
ArrayList a1=new ArrayList();
a1.add(new Person("zhangsan01",30));
a1.add(new Person("zhangsan02",31));
a1.add(new Person("zhangsan02",31));
a1.add(new Person("zhangsan03",33));
a1.add(new Person("zhangsan04",34));
a1.add(new Person("zhangsan05",35));
a1.add(new Person("zhangsan05",35));
a1=singleElement(a1);
Iterator it=a1.iterator();
while(it.hasNext())
{
Person p=(Person)it.next();
sop(p.getName()+"::"p.getAge());
}
}
public static ArrayList singleElement(ArrayList a1)
{
//定义一个临时容器
ArrayList newA1=new ArrayList();
Iterator it=a1.iterator();
while(it.hasNext())
{
Object obj=it.next();
if(!newA1.contains(obj))
newA1.add(obj);
}
return newA1;
}
}
3) Collection------>Set:
Set:特点:无序,不可以重复元素
|----HashSet:数据结构是哈希表,线程是非同步的
保证元素唯一性的原理:判断元素的hashCode值是否相同
如果相同,还会继续判断元素的equals方法是否为true
|----TreeSet:可以对Set集合中的元素进行排序。
底层数据结构是二叉树
保证元素唯一性的依据
compareTo方法return0;
TreeSet排序的第一种方式:让元素自身具备比较性,元素需要实现Comparable
接口,覆盖compareTo方法
这种方式也称为元素的自然顺序,或者叫做默认顺序
TreeSet的第二种排序方式:
当元素自身不具备比较性时,或者具备的比较性不是所需要的
这时就需要让集合自身具备比较性
在集合初始化时,就有了比较方式
重点:子类对象
HashSet:底层数据结构是哈希表
HashSet是如何保证元素唯一性的呢?
是通过元素的两个方法,hashCode()和equals()来完成的
如果元素的HashCode值相同,才会判断equals()是否为true;来进一步判断两对象内容是否相同
如果元素的hashCode值不同,不会调用equals()方法
注意:当在开发的时候如果所建的对象要放入集合中,那么在类中一般都要重写hashCode()
和equals(),它们是JVM自己调用的对于判断元素是否存在,以及删除等操作,
依赖的方法是元素的hashCode()和equals()方法。
HashSet练习:
(1)往HashSet集合中存入自定义对象
姓名年龄相同为同一个人,重复元素
class HashSetTest
{
public static void main(String[] args)
{
HashSet hs=new HashSet();
hs.add(new Person("a1",11));
hs.add(new Person("a2",12));
hs.add(new Person("a3",14));
hs.add(new Person("a4",13));
Iterator it=hs.iterator();
while(it.hasNext())
{
Person p=(Person)it.next();
sop(p.getName()+"::"+p.getAge());
}
}
public void sop(Object obj)
{
System.out.println(obj);
}
}
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.name=name;
this.age=age;
}
public int hashCode()
{
return name.hashCode()+age*28;//为了保证hashCode尽量不一样
}
public boolean equals(Object obj)
{
if(!(obj instanceof Person))
return false;
Person p=(Person)obj;
return this.name.equals(p.name)&&this.age==p.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
TreeSet练习:
(1)需求:
往TreeSet集合中存储自定义对象学生
想按照学生的年龄进行排序:
记住:排序时,主要条件相同时,一定要判断次要条件
import java.util.*;
class TreeSetDemo
{
public static void main(String[] args)
{
TreeSet ts=TreeSet();
ts.add(new Student("lisi02",22));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi01",40));
Iterator it=ts.iterator();
while(it.hasNext())
{
Student stu=(Student)it.next();
System.out.println(stu.getName()+"::"+stu.getAge());
}
}
}
class Student implements Comparable//该接口强制让学生类具备比较性,自然排序
{
private String name;
ptivate int age;
Student(String name,ing age)
{
this.name=name;
this.age=age;
}
public int compareTo(Object obj)
{
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student stu=(Student)obj;
if(this.age>stu.age)
return 1;
else if(this.age==stu.age)
{
return this.name.compareTo(s.name);
}
return 0;
return -1;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
注意:
当元素自身不具备比较性,或者具备的比较性不是所需要的
这查需要让容器自身具备比较性,定义了比较器,
将比较器对象作为参数传递给TreeSet集合的的构造函数。
import java.util.*;
class MyCompare implements Comparator
{
public int compare(Object o1,Object o2)
{
Student s1=(Student)o1;
Student s2=(Student)o2;
int num=return s1.getName().compareTo(s2.getName());
if(num==0)
{
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
}
return num;
}
}
注意:当两种排序方式都 存在时,以比较器为主
定义一个类,实现Comparator接口,覆盖compare方法
(2)按照字符串长度排序:
import java.util.*;
class TreeSetTest
{
public static void main(String[] args)
{
TreeSet ts=new TreeSet(new StrLenComparator());
ts.add("abcd");
ts.add("cc");
ts.add("cba");
ts.add("aaa");
ts.add("z");
ts.add("hahaha");
Iterator it=ts.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
}
class StrLenComparator implements Comparator
{
public int compare(Object o1,Object o2)
{
String s1=(String)o1;
String s2=(String)o2;
int num=new Integer(s1.length()).compareTo(new Integer(s2.length()));
if(num==0)
return s1.compareTo(s2);
return num;
}
}
4)Collection------>Map
接口Map<K,V>集合:该集合存储键值对,一对一对往里存,而且要保证键的唯一性
常用操作:
1.添加
V put(K key,V value);
putAll(Map<? extends K,?extends V> m)
2.删除
remove(Object key)
clear();
3.判断
isEmpty();
containsValue(Object value);
containsKey(Object key);
4.获取
V get(Object key);
size();
Values();
entrySet();
keySet();
K-此映射所维护的键的类型
V-映射值的类型
将键映射到值的对象,一个映射不能包含重复的键;每个键最多只能映射到一个值
|--Hashtable:底层数据结构是哈希表,不可以存入null键 ,null值 该集合是线程同步的,jdk1.0效率低
|--HashMap:底层数据结构是哈希表,并允许使用null键,null值,该集合是不同步的。jdk1.2效率高
|--TreeMap:底层数据结构是二叉树线程不同步,可以用于给map集合中的键进行排序
Map和Set很像
其实,Set底层就是使用了Map集合
import java.util.*;
class MapDemo
{
public static void main(String[] args)
{
Map<String,String> map=new HashMap<String,String>();
//添加元素,添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有键对应值。并用put返回被覆盖的值
map.put("01","zhangsan1");
map.put("02","zhangsan2");
map.put("03","zhangsan3");
System.out.println("containsKey:"+map.containsKey("022"));
//删除元素
System.out.println("remove:"+map.remove("02"));
System.out.println(map);
System.out.println("get:"+map.get("023"));
map.put("04",null);
System.out.println("get:"+map.get("04"));//可以通过get方法的返回值来判断一个键是否存在
通过返回null来判断
//获取map集合中所有的值
Collection<String> coll=map.values();
}
}
map集合的两种取出方式:
1.keySet();将map中所有的键存入到Set集合,因为Set具备迭代器,再根据get方法,获取每一个键对应的值
Map集合的取出原理:将map集合转成Set集合,再通过 Set集合的迭代器取出 key,再用map.get(key);
比如:
import java.util.*;
class MapDemo2
{
public static void main(String[] args)
{
Map<String,String> map=new HashMap<String,String>();
map.put("02","zhangsan2");
map.put("03","zhangsan3");
map.put("01","zhangsan1");
map.put("04","zhangsan4");
//先获取map集合的所有键的Set集合,keyset();
Set<String> keySet=map.keySet();
//有了Set集合,就可以获取其迭代器
Iterator<String> it=keySet.iterator();
while(it.hasNext())
{
String key=it.next();
String value=map.get(key);
System.out.println("key:"+key,"value:"+value);
}
}
}
2.Set<Map.Entry<K,V>> entrySet(); 将Map集合中的映射关系存入到了Set集合中,
而这个关系的数据类型就是:MapEntry<K,V>
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+":"+value);
}
Map.Entry:其实Entry也是一个接口,它是Map接口中的一个内部接口
Interface Map
{
public static interface Entry
{
public abstract Object getKey();
public abstract Object getValue();
}
}
class HashMap implements Map
{
class Haha implements Map.Entry
{
public Object getKey();
public Object getValue();
}
}
Map练习:
(1)需要:每一个学生都有对应的归属地
学生Student,地址String
学生属性:姓名,年龄
注意:姓名和年龄相同的视为同一个学生
保证学生的唯一性
步骤:
1.描述学生
2.定义Map容器,将学生作为键,地址作为值,存入
3.获取Map集合中的元素
import java.util.*;
class Student implements Comparable<Student>
{
private String name;
private int age;
Student(String name,int age)
{
this.name=name;
this.age=age;
}
public int compareTo(Student s)
{
int num=new Integer(this.age).compareTo(new Integer(s.age));
if(num==0)
return this.name.compareTo(s.name);
return num;
}
public int hashCode()
{
return name.hashCode()+age*34;
}
public boolean equals(Object obj)
{
if(!(obj instanceof Student))
throw new ClassCastException("类型不匹配");
Student s=(Student)obj;
return this.name.equals(s.name)&&this.age==s.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public String toString()
{
return name+":"+age;
}
}
class MapTest
{
public static void main(String[] args)
{
HashMap<Student,String> hm=new HashMap<Student,String>()
hm.put(new Student("lisi1",21),"beijing");
hm.put(new Student("lisi2",22),"shanghai");
hm.put(new Student("lisi3",23),"nanjing");
hm.put(new Student("lisi4",24),"wuhan");
}
//第一种取出的方式:keySet
Set<Student> keySet=hm.keySet();
Iterator<Student> it=keySet.iterator();
while(it.hasNext())
{
Student stu=it.next();
String addr=hm.get(stu);
System.out.println(stu+":"+addr);
}
//第二种取出方式,entrySet
Set<Map.Entry<Student,String>> entrySet=hm.entrySet();
Iterator<Map.Entry<Student,String>> iter=entrySet.iterator();
while(iter.hasNext())
{
Map.Entry<Student,String> me=iter.next();
Student stu=me.getKey();
String addr=me.getValue();
System.out.println(stu+":"+value);
}
}
(2)需求:对学生对象的年龄进行升序排序
因为数据是以键值对形式存在的
所以要使用可以排序的Map集合,TreeMap
import java.util.*;
class StuNameComparator implements Comparator<Student>
{
public int compare(Student s1,Student s2)
{
int num=s1.getName().compareTo(s2.getName());
if(num==0)
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
return num;
}
}
class MapTest2
{
public static void main(String[] args)
{
TreeMap<Student,String> tm=new TreeMap<Student,String>(new StuNameComparator());
tm.put(new Student("alisi3",23),"nanjing");
tm.put(new Student("blisi1",21),"beijing");
tm.put(new Student("lisi2",22),"tianjing");
tm.put(new Student("lisi4",24),"wuhan");
Set<Map.Entry<Student,String>> entrySet=tm.entrySet();
Iterator<Map.Entry<Student,String>> it=entrySet.iterator();
while(it.hasNext())
{
Map.Entry<Student,String> me=it.next();
Student stu=me.getKey();
String addr=me.getValue();
System.out.println(stu+"...."+addr);
}
}
}
(3)"sdfgzxcvasdfxcvdf"获取该字符串中的字母出现的次数
希望打印结果:a(1)c(2)……
思考:通过结果发现,每一个字母都有对应的次数
说明字母和次数之间都有映射关系
当发现有映射关系时,可以选择map集合
因为map集合中存放的就是映射关系
什么时候使用map集合呢?
当数据之间存在着映射关系时,就要先想到map集合
思路:
1.将字符串转换成字符数组,因为要对每一个字母进行操作
2.定义一个map集合,因为打印结果的字母有顺序 ,所以使用treemap集合
3.遍历字符数组
将每一个字母作为键去查map集合
如果返回null,将该字母和1存入到map集合中
如果返回不是null,说明该字母在map集合已经存在并有对应次数
那么就获取该次数并进行自增,然后将该字母和自增后的次数存入到map集合中,覆盖原来键所对应的值
4.将map集合中的数据变成指定的字符串形式返回
import java.util.*;
class MapTest3
{
public static void main(String[] args)
{
String s=charCount("afdgdfeijeijfgeiea");
System.out.println(s);
}
public static String charCount(String str)
{
char[] chs=str.toCharArray();
TreeMap<Character,Integer> tm=new TreeMap<Charactor,Integer>();
int count=0;
for(int x=0;x<chs.length;x++)
{
if(!(chs[x]>='a'&&chs[x]<='z'||chs[x]>='A'&&chs[x]<='Z'))
continue;
Integer value=tm.get(chs[x]);
//优化一下:
if(value==!null)
count=value;
count++;
tm.put(chs[x],count);
count=0;
/*if(value==null)
{
tm.put(chs[x],1);
}
else
{
value=value+1;
tm.put(chs[x],value);
}*/
}
StringBuilder sb=new StringBuilder();
Set<Map.Entry<Charactor,Integer>> entrySet=tm.entrySet();
Iterator<Map.Entry<Character,Integer>> it=entrySet.iterator();
while(it.hasNext())
{
Map.Entry<Charactor,Integer> me=it.next();
Charactor ch=me.getKey();
Integer value=me.getValue();
sb.append(ch+"("+value+")");
}
return sb.toString();
}
}
map扩展知识 :
map集合被使用是因为具备映射关系
"yureban" Student("01 " "zhangsan")
"yereban" Student( "02" "lisi")
"jiuyeban" "01" "wangwu"
"jiuyeban" "02" "zhaoliu"
一个学校有多个教室,每一个教室都有名称
import java.util.*;
class Student
{
private String id;
private String name;
Student(String id,String name)
{
this.id=id;
this.name=name;
}
public String toString()
{
return id+":::"+name;
}
}
class MapDemo3
{
public Static void demo()
{
HashMap<String,List<Student>> czbk=new HashMap<String,String,List<Student>>();
List<Student> yure1=new ArrayList<Student>();
list<Student> jiuye1=new ArrayList<Student>();
czbk.put("yureban",yure1);
czbk.put("jiuyeban",jiuye1);
yure1.add(new Student("01","zhangsan"));
yure1.add(new Student("02","lisi"));
jiuye1.add(new Student("01","wangwu"));
jiuye1.add(new Student("02","zhaoliu"));
Iterator<String> it=czbk.keySet().iterator()
while(it.hasNext())
{
String roomName=it.next();
List<Student> room=czbk.get(roomName);
System.out.println(roomName);
getInfos(room);
}
}
public static void getInfos(List<Student> list)
{
Iterator<Student> it=list.iterator();
while(it.hasNext())
{
Student stu=it.next();
System.out.println(id+"::"+name);
}
}
public static void main(String[] args)
{
demo();
/*HashMap<String,HashMap<String,String>>czbk=new HashMap<String,HashMap<String,String>();
HashMap<String,String>yure=new HashMap<String,String>();
HashMap<String,String>jiuye=new HashMap<String,String>();
czbk.put("yureban",yure);
czbk.put("jiuyeban",jiuye);
yure.put("01","zhangsan");
yure.put("02","lisi");
jiuye.put("01","wangwu");
jiuye.put("02","zhaoliu");
//getStudentInfo(yure);
/getStudentInfo(jiuye);
//遍历czbk集合,获取所有的教室
Iterator<String> it=czbk.keySet().iterator()
while(it.hasNext())
{
String roomName=it.next();
HashMap<String,String> room=czbk.get(roomName);
System.out.println(roomName);
getStudentInfo(room);
}
}
public static void getStudentInfo(HashMap<String,String> roomMap)
{
Iterator<String> it=roomMap.keySet().iterator();
while(it.hasNext())
{
String id=it.next();
String name=roomMap.get(id);
System.out.println(id+"::"+name);
}
}
*/
}
---------------------- android培训、java培训、期待与您交流! ----------------------