-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
Java基础之集合框架
1.什么是集合,集合的作用:
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就要 对对象进行存储,集合就是存储对象最常用的一种方式。
数组和集合类同是容器,再者之间存在不同:数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储任意数据类型,集合只能存储对象。
集合类的特点 :集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
2.集合框架的构成及分类:
如上图,集合类两大接口为两大接口 :Collection,Map,这两个接口为集合框架中的顶级接口,其它具体的类都是根据数据存储方式不同,通过直接或间接实现这两个接口而产生的,主要包括的类有:
Collection实现 | Map实现 | ||
元素有序、可重复 | 元素无序,不可重复 | 无序 | |
ArrayList() linkedList | HashSet treeSet | HashMap TreeMap |
3.主要集合类API介绍
3.1先看下Collection接口中定义的 方法:
方法摘要(来自API文档) | ||
boolean | ||
boolean | addAll(Collection<? extendsE> c)将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。 | |
void | clear()移除此 collection 中的所有元素(可选操作)。 | |
boolean | ||
boolean | containsAll(Collection<?> c)如果此 collection 包含指定 collection 中的所有元素,则返回 true。 | |
boolean | ||
boolean | isEmpty()如果此 collection 不包含元素,则返回 true。 | |
iterator()返回在此 collection 的元素上进行迭代的迭代器。 | ||
boolean | ||
boolean | removeAll(Collection<?> c)移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。 | |
boolean | retainAll(Collection<?> c)仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)。 | |
int | size()返回此 collection 中的元素数。 | |
Object[] | toArray()返回包含此 collection 中所有元素的数组。 | |
| toArray(T[] a)返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。 |
3.2ArrayList内部存储数据的数组结构,LinkedList内部存储数据的是链表结构,两都都是Collection接口的间接实现类,对Collection接口中的操作元素增删改查的方法有具体的实现(具体可查找API文档);例如:ArrayList操作数据增删改查方法:
*******************************************************************
publicstaticvoidmain(String[] args) {
//创建四个对象
Person person1 = newPerson(20,"张三","深圳");
Person person2 = newPerson(26,"李四","广州");
Person person3 = newPerson(25,"王五","上海");
Person person4 = newPerson(23,"赵六","北京");
//实例一个ArrayList集合
List<Person>persons = new ArrayList<Person>();
//将以上Person对象放入ArrayList集合中
persons.add(person1);
persons.add(person2);
persons.add(person3);
persons.add(person4);
System.out.println("集合开始元素个数为:" +persons.size());
// 用迭代器遍历集合中的元素
Iterator<Person> iterator =persons.iterator();
while(iterator.hasNext()) {
Person person = (Person)iterator.next();
System.out.println(person);
}
// 用增加FOR遍历集合
for(Person person : persons) {
System.out.println(person);
}
// 用get方法拿到指定的元素
System.out.println(persons.get(0));
System.out.println(persons.get(1));
System.out.println(persons.get(2));
System.out.println(persons.get(3));
// 根据下标删除元素(删除前面的元素后,后面的元素被移到前面)
persons.remove(0);
persons.remove(1);
System.out.println("根据下标删除元素后集合元素个数为:" +persons.size());//得到集合中元素个数
// 删除指定元素
persons.remove(person4);
System.out.println("删除指定元素后集合元素个数为:" +persons.size());
// 根据下标值将指定位置中的元素替换掉
persons.set(0, newPerson(25,"王二麻子","天津"));
System.out.println(persons);
}
*******************************************************************
3.3 Set接口 (元素不可以重复)
Set是Collection子接口; Set和Collection基本上一样,但存在不同: Set无法记住添加的顺序,不允许包含重复的元素。 当试图添加两个相同元素进Set集合,添加操作失败,add()方法返回false。
Set判断两个对象是否相等用equals,而不是使用 “==”,也就是说两个对象equals比较返回true,Set集合是不会接受这个两个对象的。
Setr接口常用子类: HashSet:散列存放,TreeSet:有序存放。
HashSet类是Set接口最常用的实现类,采用哈希算法存储数据,具有良好的存储和查找功能。HashSet线程不安全的,多个线程访问一个HashSet要使用同步代码;
当从HashSet中访问元素时,HashSet先计算该元素的hashCode(也就是该对象的hashCode方法返回值),然后直接到该HashCode对应的位置取出该元素;
HashSet操作元素的增删改查:
*******************************************************************
Person person1 = newPerson(20,"张三","深圳");
Person person2 = newPerson(26,"李四","广州");
Person person3 = newPerson(25,"王五","上海");
Person person4 = newPerson(23,"赵六","北京");
//构造一个集合
Set<Person>persons = new HashSet<Person>();
persons.add(person1);
persons.add(person2);
persons.add(person3);
persons.add(person4);
System.out.println("集合开始元素个数为:" +persons.size());
// 用迭代器遍历集合中的元素
Iterator<Person> iterator =persons.iterator();
while(iterator.hasNext()) {
Person person = (Person)iterator.next();
System.out.println(person);
}
System.out.println("----------黄金分割线1------------");
// 用增加FOR遍历集合(与存放进去的顺序不同)
for(Person person : persons) {
System.out.println(person);
}
persons.remove(person4);//没有下标,通过指定对象来删除相应的元素
*******************************************************************
当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对 象的hashCode 值,判断已经存储在集合中的对象的hashCode 值是否与添加的对象的 hashCode值一致:若不一致:直接添加进去;若一致,再进行equals方法比较,equals方法如果返回true,表明对象已经添加进去了,就不会再添加新的对象了,否则添加进去; 因此,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象 的hashCode方法返回值也相等。
TreeSet是SortedSet接口唯一的实现,与HashSet相比额外的方法有:
Comparator comparator():返回当前Set使用的Comparator,若返回null,表示以自然顺序排序。
Object first() 返回此 set 中当前第一个(最低)元素。
Object last() 返回此 set 中当前最后一个(最高)元素。
SortedSet subSet(Object fromElement, EtoElement) 返回此 set 的部子集,其元素从 fromElement (包括)到toElement (不包括)。
SortedSet headSet(Object toElement)返回此 set 的部分子集,其元素严格小于toElement。
SortedSet tailSet(Object fromElement) 返回此 set 的部分子集,其元素大于等于romElement。
TreeSet的排序 :① TreeSet会调用元素的compareTo(Objecto)方法来比较元素之间的大小关系,然后将集合里的 元素按升序排列.此时需要排序元素的类必须实现Compareble接口,并覆写其int compareTo(Objecto)方法; 该方法用于比较对象,若:obj1.compareTo(obj2),返回0,表示两个对象相等,若返回一个正整数, 表示obj1大于obj2,若返回一个负整数,表示obj1小于obj2; 对于TreeSet集合而言,判断两个对象相等的标准是: compareTo()方法比较返回0; ②还可以通知在构造TreeSet的时候传递一个Comparator接口的实现类来实现内部排序的方式,这种方式要求Comparator的实现类重写compare(o1, o2) 方法,信用根据内部自自动调用这个方法比较两个对象是否相同(与Compareble比较方式一样,不详细说明);当两方式同时出现时,集合将以第二种方式为排序方式,第一种排序如下:
*******************************************************************
第一步:对象实现Comparable接口,重写compareTo方法:
publicclassPersonimplements Comparable<Person> {
@Override
publicintcompareTo(Person o) {//如果姓名,年龄,地址都相同视为同一个人,否则,选进入集合的对象将排到前面
if (this.name.equals(o.name)&&this.addr.equals(o.addr)
&& this.age ==o.age) {
return 0;
}
return 1;
}
}
第二步:将实例对象放入集合中,打印出来的结果为先放入的先打印出来,后放入的在后面(代码省略)。
*******************************************************************
第二种排序方式:
*******************************************************************
第一步:定义一个实现Comparator接口的类,重写compare方法:
public classMyComparator implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {//如果姓名,年龄,地址都相同视为同一个人,否则,选进入集合的对象将排到后面
if (o1.getName().equals(o2.getName())
&&o1.getAddr().equals(o2.getAddr())
&& o1.getAge() ==o2.getAge()) {
return 0;
}
return -1;
}
}
第二步:实例TreeSet集合的时候将以上定义好的Comparator接口实现类的一个实例传给集合,作为排序用:
Set<Person>persons = new TreeSet<Person>(new MyComparator());
第三步:实例化对象将其放入集合中,排序方式将按Comparator接口实现类的规则进行(代码略去)。
*******************************************************************
3.4map集合的操作
Map集合储存元素的方式是以键值对(key,value)的方式进行存放,其中,key值是唯一的,不可以重复,value值可以重复,如果key值重复,后放入的元素会对前面放入的元素进行复盖,Map接口中定义的操作元素的方法:
方法摘要 | |
| clear |
| containsKey |
| containsValue |
| |
| isEmpty |
| putAll |
| size |
values |
Map集合常用的类包括HashMap(key值可以为null),TreeMap(key值不可以为null)两个。
Map集合中存放的是健值对的数据结构,由于MAP集合没有迭代器,没有下标索引,所以不能通过直接遍历的方式将元素取出,需要通过转化其它集合的方式遍历元素:
方式一:先将key值集合取出,通过遍历此集合,得到每个对应的value值;
方式二:通过entrySet()方法将集合内部元素的关系转化为Set集合,通过操作这个集合将元素取出来。例如:
*******************************************************************
Person person1 = newPerson(20,"张三","深圳");
Person person2 = newPerson(26,"李四","广州");
Person person3 = newPerson(25,"王五","上海");
Person person4 = newPerson(23,"赵六","北京");
Map<String, Person> map = newHashMap<String, Person>();
map.put("小张", person1);
map.put("小李", person2);
map.put("老王", person3);
map.put("老赵", person4);
map.put("小赵", person4);
map.put("小赵",newPerson(24,"赵子龙","常山"));//与上面的元素KEY值相同,后者复盖前者
// 第一种取出方式:
Set<String> keys = map.keySet();
for(Stringkey : keys){
Person person = map.get(key);
System.out.println(key +"::" +person);
}
// 第二种取出方式
Set<Entry<String, Person>>entrys = map.entrySet();
for(Entry<String, Person> entry : entrys) {
System.out.println(entry.getKey()+":--:" + entry.getValue());
}
}
*******************************************************************
4.集合工具类使用
为方面更好的操作集合,我们可以利用集合的工具类的方法帮助我们的开发,其中常用的类有:
Collections类,操作集合的工具类,常用的方法有:
Static void reverse(Listlist):反转指定List集合中的顺序;
Static void shuffle(Listlist):对集合元素随机排序
Static void sort(Listlist):自然升序排序
Static void swap(Listlist,inti,intj):将指定的List集合i处元素和j处元素进行交换;
Static void rotate(Listlist,int distance):
若distance为正数,将list集合后的distance个元素移到前面;
当distance为负数,将list集合前的distance个元素移到后面;
static int binarySearch(Listlist,Object key) 使用二分搜索法搜索指定列表,以获得指定对象。调用之前必须调用Collections.sort(Listlist)(完成自然排序);
static Object max(Collectioncoll) 根据元素的自然顺序,返回给定collection的最大元素。
Static Object min(Collectioncoll) 根据元素的自然顺序,返回给定collection的最小元素。
static void fill(Listlist,Object obj) 使用指定元素替换指定列表中的所有元素。
Static int frequency(Collectionc,Objecto)返回指定collection中等于指定对象的元素数。
Static int indexOfSubList(Listsource,Listtarget)返回指定源列表中第一次出现指定目标列表的起始位置;如果没有出现这样的列表,则返回-1。例如:
*******************************************************************
Person person1 =new Person(20,"张三","深圳");
Person person2 = newPerson(26,"李四","广州");
Person person3 = newPerson(25,"王五","上海");
Person person4 = newPerson(23,"赵六","北京");
List<Person> persons = newArrayList<Person>();
persons.add(person1);
persons.add(person2);
persons.add(person3);
persons.add(person4);
System.out.println("集合开始元素个数为:" +persons.size());
// 用增加FOR遍历集合
for(Person person : persons) {
System.out.println(person);
}
// 将集合中的元素反转
Collections.reverse(persons);
System.out.println("-------反转后-------");
for(Person person : persons) {
System.out.println(person);
}
// 对集合中的元素随机排序(每次排序的结果不一样)
Collections.shuffle(persons);
System.out.println("-------随机排序后-------");
for(Person person : persons) {
System.out.println(person);
}
// 对集合中的元素随机排序(每次排序的结果不一样)
Collections.sort(persons);
System.out.println("-------升序排序后-------");
for(Person person : persons) {
System.out.println(person);
}
// 最小值(按自然排序后的结果)
System.out.println(Collections.min(persons));
*******************************************************************
小结:集合是用于存放对象的容器,集合框架中现个顶级的接口为Collection和Map,其它集合类都是这两个集合的实现类,每个集合类都包括了操作集合元素的基本方法:
分类 | 增加相关 | 删除相关 | 查询相关 |
Collection | Add(obj) addAll | removeAll clear | iterator
|
Map | clear | entrySet |