黑马程序员--集合(一)
2015-11-07 18:07
495 查看
黑马程序员--集合(一)
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
集合类的特点:只用于存储对象,长度可变,可存储不同类型的对象。
PS:
集合类和数组都是容器,有何不同?
数组长度固定,且只能存相同类型的对象。
集合长度可变;数组可储存基本数据类型,集合只能储存对象。
2、集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。
任何集合框架都包含三大块内容:对外的接口、接口的实现和对集合运算的算法。
集合框架的优点:
简化程序设计;提高程序效率;提高API的使用效率;提高代码复用性。
集合框架的构成和分类:
1、常见方法:
1.1添加:
boolean add(Object obj);
boolean addAll(Collection coll);
1.2删除
boolean remove(Object obj);
boolean removeAll(Collection coll);
void clear();
1.3判断
boolean contains(Object obj);
boolean containsAll(Collection coll);
boolean isEmpty();判读集合中是否有元素。
1.4获取
int size();
Iterator iterator():返回迭代器接口。
迭代器接口:对所有Collection容器进行元素取出的公共接口。
具体方法:
hasNext():若仍有元素可迭代,则返回true。
next():返回迭代的下一个元素。
remove():从迭代器指向的collection中移除迭代器返回的最后一个元素。
PS:
由于不同集合数据结构不同,造成每一个集合存取的方式可能不同。一般当我们需要多个动作(判断、取出)
才能完成一个动作的取出时,我们就将取出动作封装成一个对象。同时,因为其操作元素在集合中,
通过定义内部类,取出方式就可以直接访问集合内容元素。同时,我们将内部类都符合的取出方式规则定义在Iterator接口中,
通过iterator()方法获取。
1.5其他
boolean retainAll(Collection coll):取交集
Object toArray():将集合转成数组
2、List、Set接口
2.1 List接口
2.1.1 List常见方法:
这些方法有一个共性特点:都可以操作角标。
2.1.1.1 添加
void add(index,element);
void addAll(index,Collection);
2.1.1.2 删除
Object remove(index);
2.1.1.3 修改
Object set(index,element);
2.1.1.4 获取
Object get(index);
int indexOf(object);
int lastIndexOf(object);
List subList(form,to);//展现列表
2.1.1.5 ListIterator接口
ListIterator接口是Iterator的子接口。它是List集合特有的迭代器。它只能通过listIterator()方法获取。
Iterator方法只能对元素进行判断、取出、删除的操作,当迭代器需要增加元素等操作时,必须通过集合的方法,
这是会出现并发访问异常,存在安全隐患。ListIterator接口扩展了Iterator接口功能。避免了混合使用集合问题。
ListIterator接口常见方法:
add();
hasNext():正向遍历;
hasPrevious():逆向遍历;
next():返回列表中下一个元素;
previous():返回列表中的前一个元素;
remove():移除元素;
set():替换。
2.1.2List分类:
List:元素是有序的,元素可以重复。因为该集合体系有索引。
|--Vector:底层是数组数据结构。线程同步。Vector生成20容量的数组,但是较浪费空间。被ArrayList替代。
|--ArrayList:底层是数组数据结构。线程不同步。特点:查询块;增删慢。可变长度数组:超过10后,生成15容量的数组。
|--LinkedList:底层使用的链表数据结构。特点:增删快;查询慢。
JDK1.6后方法:
PS:
Enumeration(枚举):是Vector特有的取出方式。枚举和迭代功能一样。
2.2 Set接口
Set接口中元素不可以重复,无序(存入和输出顺序不一定一致)。它的方法和Collection一致。
HashSet保证元素唯一性原理:判断元素的hashCode值是否相同。
如果元素的哈希值相同,才会判断对象内容是否相同。
PS:
1、判断元素是否存在,以及删除等操作,HashSet依赖的方法是元素的hashCode和equals方法;
而ArrayList只依赖equals方法。TreeSet保证元素唯一性的依据compareTo方法。
原因:数据结构不同,所依赖方法也不一样。
2、让HashSet无序变有序,可使用LinkedHashSet。
2.2.1TreeSet排序
a 元素的自然顺序(默认顺序)。让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。
b 自定义比较器。让集合自身具备比较性:定义一个类,实现Comparator接口,覆盖compare方法。将该类对象
作为参数传递给TreeSet集合的构造函数。这种方法适用于:元素自身不具备比较性或不具备自己所需的比较性。
当两种方式都存在时,以比较器为主。
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
集合类
一、概述
1、集合类:储存对象最常用的方式的方式之一。数据多了用对象存,对象多了用集合存。集合类的特点:只用于存储对象,长度可变,可存储不同类型的对象。
PS:
集合类和数组都是容器,有何不同?
数组长度固定,且只能存相同类型的对象。
集合长度可变;数组可储存基本数据类型,集合只能储存对象。
2、集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。
任何集合框架都包含三大块内容:对外的接口、接口的实现和对集合运算的算法。
集合框架的优点:
简化程序设计;提高程序效率;提高API的使用效率;提高代码复用性。
集合框架的构成和分类:
二、Collection接口
框架的顶层-->Collection接口:1、常见方法:
1.1添加:
boolean add(Object obj);
boolean addAll(Collection coll);
1.2删除
boolean remove(Object obj);
boolean removeAll(Collection coll);
void clear();
1.3判断
boolean contains(Object obj);
boolean containsAll(Collection coll);
boolean isEmpty();判读集合中是否有元素。
1.4获取
int size();
Iterator iterator():返回迭代器接口。
迭代器接口:对所有Collection容器进行元素取出的公共接口。
具体方法:
hasNext():若仍有元素可迭代,则返回true。
next():返回迭代的下一个元素。
remove():从迭代器指向的collection中移除迭代器返回的最后一个元素。
PS:
由于不同集合数据结构不同,造成每一个集合存取的方式可能不同。一般当我们需要多个动作(判断、取出)
才能完成一个动作的取出时,我们就将取出动作封装成一个对象。同时,因为其操作元素在集合中,
通过定义内部类,取出方式就可以直接访问集合内容元素。同时,我们将内部类都符合的取出方式规则定义在Iterator接口中,
通过iterator()方法获取。
1.5其他
boolean retainAll(Collection coll):取交集
Object toArray():将集合转成数组
import java.util.*; /* 1.add方法的参数类型是Object.以便于接收任意类型对象。 2.集合中存储的都是对象的引用(地址)。 3.集合变数组。 Collection接口中的toArray方法。 3.1指定类型的数组到底要定义多长? 当指定类型的数组长度小于集合的size,那么该方法内部会创建一个新的数组。 当指定类型的数组长度大于集合的size,就不会创建一个新的数组。而是使用传递进来的数组。 所以创建一个刚刚好的数组内存处置最优。 3.2为什么要将集合变数组? 当不需要对集合元素增删时,可限定对元素的操作。因为数组长度固定。 */ class CollectionDemo { public static void main(String[] args) { base_method(); other_method(); } public static void base_method() { Collection col1 = new ArrayList(); //添加元素 col1.add("java01"); col1.add("java02"); col1.add("java03"); sop("col1添加:"+col1); Collection col2 = new ArrayList(); col2.addAll(col1); sop("col2添加:"+col2); //删除元素 sop("删除java02:"+col1.remove("java02")); col1.clear(); sop("清空后集合"+col1); //判断元素 sop("java03是否存在:"+col1.contains("java03")); sop("col2是否为空?"+col2.isEmpty()); //获取 sop("获取col2中元素个数:"+col2.size()); //获取迭代器,取出集合中的元素。接口性引用只能指向自己的子对象。it随for循环结束而释放,更节省内存。 for(Iterator it = col2.iterator();it.hasNext();) { System.out.print(it.next()+" "); } System.out.println(); Collection col3 = new ArrayList(); col3.add("java02"); col3.add("java05"); sop("col2:"+col2); //取交集,去除交集 col3.retainAll(col2); sop("取交集:"+col3); col3.removeAll(col2); sop("移除相同元素:"+col3); } public static void other_method() { Collection<String> col4 = new ArrayList<String>(); col4.add("abc1"); col4.add("abc2"); col4.add("abc3"); //将集合转成数组 String[] arr = col4.toArray(new String[col4.size()]); sop("集合转数组:"+Arrays.toString(arr)); } public static void sop(Object obj) { System.out.println(obj); } }运行结果:
2、List、Set接口
2.1 List接口
2.1.1 List常见方法:
这些方法有一个共性特点:都可以操作角标。
2.1.1.1 添加
void add(index,element);
void addAll(index,Collection);
2.1.1.2 删除
Object remove(index);
2.1.1.3 修改
Object set(index,element);
2.1.1.4 获取
Object get(index);
int indexOf(object);
int lastIndexOf(object);
List subList(form,to);//展现列表
import java.util.*; class ListDemo { public static void main(String[] args) { base_method(); } public static void base_method() { List li = new ArrayList(); //添加元素 li.add("java01"); li.add("java03"); li.add("java03"); sop("添加元素:"+li); //删除指定位置的元素 li.remove(2); sop("被删除后的集合:"+li); //修改元素 li.set(1,"java02"); sop("被修改后的集合"+li); li.add(2,"java02"); sop("定点添加:"+li); //通过角标获取元素 sop("get(1):"+li.get(1)); //获取所有元素 for(int x=0;x<li.size();x++) { System.out.print("li("+x+")="+li.get(x)+" "); } System.out.println(); for(Iterator it = li.iterator();it.hasNext();) { System.out.print("next:"+it.next()+" "); } System.out.println(); //通过indexOf获取对象的位置 sop("index="+li.indexOf("java02")); sop("lastIndexOf:"+li.lastIndexOf("java02")); List sub = li.subList(0,3); sop("sub"+sub); } public static void sop(Object obj) { System.out.println(obj); } }运行结果:
2.1.1.5 ListIterator接口
ListIterator接口是Iterator的子接口。它是List集合特有的迭代器。它只能通过listIterator()方法获取。
Iterator方法只能对元素进行判断、取出、删除的操作,当迭代器需要增加元素等操作时,必须通过集合的方法,
这是会出现并发访问异常,存在安全隐患。ListIterator接口扩展了Iterator接口功能。避免了混合使用集合问题。
ListIterator接口常见方法:
add();
hasNext():正向遍历;
hasPrevious():逆向遍历;
next():返回列表中下一个元素;
previous():返回列表中的前一个元素;
remove():移除元素;
set():替换。
//获取数据的方法有两种:迭代器和集合,当两种方式混合使用时,会发生-->并发访问异常。 import java.util.*; class ListDemo2 { public static void main(String[] args) { iterator_method(); } public static void iterator_method() { //演示列表迭代器 List li = new ArrayList(); //添加元素 li.add("java01"); li.add("java02"); li.add("java03"); sop("li="+li); //本例中,li是集合;it是迭代器。当两种方式访问同一数据时,会存在安全隐患。 for(Iterator it = li.iterator();it.hasNext();) { //因为要判断的it.next()要==java02,所以obj(即it)为java01。 Object obj = it.next(); if(obj.equals("java02")) //因为迭代器只有移除方法,没有添加,所以需要借助集合的add()方法。 li.add("java008"); it.remove(); //会输出java01,因为remove只移除了引用,对象还存在。 sop("obj="+obj); sop("li="+li); } sop(li); } public static void sop(Object obj) { System.out.println(obj); } }运行结果:
/* List定义了自己的迭代器接口:ListIterator()。避免Itetator接口中可使用方法较少,混合使用集合和迭代器的问题。 ListIterator是Iterator的子接口。该接口只能通过List集合的listIterator方法获取。 */ import java.util.*; class ListDemo3 { public static void main(String[] args) { iterator_method(); } public static void iterator_method() { //演示列表迭代器 List li = new ArrayList(); //添加元素 li.add("java01"); li.add("java03"); li.add(1,"java02"); sop("li="+li); //其可以增、改、查的原因是它带角标。 ListIterator lit = li.listIterator(); //判断迭代前有没有元素 sop("hasPrevious():"+lit.hasPrevious()); while(lit.hasNext()) { Object obj = lit.next(); //替换元素 if(obj.equals("java02")) lit.set("java007"); } //判断迭代后有没有元素 sop("hasNext():"+lit.hasNext()); sop("hasPrevious():"+lit.hasPrevious()); sop("li="+li); } public static void sop(Object obj) { System.out.println(obj); } }运行结果:
2.1.2List分类:
List:元素是有序的,元素可以重复。因为该集合体系有索引。
|--Vector:底层是数组数据结构。线程同步。Vector生成20容量的数组,但是较浪费空间。被ArrayList替代。
|--ArrayList:底层是数组数据结构。线程不同步。特点:查询块;增删慢。可变长度数组:超过10后,生成15容量的数组。
|--LinkedList:底层使用的链表数据结构。特点:增删快;查询慢。
import java.util.*; class LinkedListDemo { public static void main(String[] args) { LinkedList link = new LinkedList(); //先存的为尾 link.addFirst("java01"); link.addFirst("java02"); link.addFirst("java03"); sop("link="+link); sop("获取尾元素:"+link.getFirst()); sop("获取头元素:"+link.getLast()); sop("移除尾元素:"+link.removeFirst()); sop("link="+link); } public static void sop(Object obj) { System.out.println(obj); } }运行结果:
JDK1.6后方法:
/* 使用LinkedList模拟一个堆栈或者队列数据结构。 堆栈:先进后出 如同杯子。 队列:先进先出 如同水管。 */ import java.util.*; class DuiLie { private LinkedList link; DuiLie() { link = new LinkedList(); } //先入的为尾 public void myAdd(Object obj) { link.offerFirst(obj); } //获取并删除先存入的元素 public Object myGet() { return link.pollLast(); } public boolean isNull() { return link.isEmpty(); } } class LinkedListTest { public static void main(String[] args) { DuiLie dl = new DuiLie(); dl.myAdd("java01"); dl.myAdd("java02"); dl.myAdd("java03"); while(!dl.isNull()) { System.out.print(dl.myGet()+" "); } System.out.println(); } }运行结果:
PS:
Enumeration(枚举):是Vector特有的取出方式。枚举和迭代功能一样。
2.2 Set接口
Set接口中元素不可以重复,无序(存入和输出顺序不一定一致)。它的方法和Collection一致。
HashSet保证元素唯一性原理:判断元素的hashCode值是否相同。
如果元素的哈希值相同,才会判断对象内容是否相同。
PS:
1、判断元素是否存在,以及删除等操作,HashSet依赖的方法是元素的hashCode和equals方法;
而ArrayList只依赖equals方法。TreeSet保证元素唯一性的依据compareTo方法。
原因:数据结构不同,所依赖方法也不一样。
2、让HashSet无序变有序,可使用LinkedHashSet。
import java.util.*; /* 通过hashSet集合判断Person对象是否相同。姓名和年龄相同视为重复元素。 */ class Person { private String name; private int age; Person(String name,int age) { this.name = name; this.age = age; } //复写hashCode() public int hashCode() { //看hashCode的调用记录 System.out.println(this.name+"....hashCode()"); //字符串name有自己的hashCode值,排除和相同的情况 return name.hashCode()+age*37; } //复写equals public boolean equals(Object obj) { if(!(obj instanceof Person)) return false; //向下转型。因为要使用Person自己的方法。 Person p = (Person)obj; System.out.println(this.name+"...equals.."+p.name); return this.name.equals(p.name) && this.age == p.age; } public String getName() { return name; } public int getAge() { return age; } } 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",13)); hs.add(new Person("a4",13)); for(Iterator it = hs.iterator();it.hasNext();) { Person p = (Person)it.next(); sop(p.getName()+"...."+p.getAge()); } } public static void sop(Object obj) { System.out.println(obj); } }运行结果:
2.2.1TreeSet排序
a 元素的自然顺序(默认顺序)。让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。
/* 需求:往TreeSet集合中存储自定义对象学生。按照学生的年龄进行排序。 注意:排序时,当主要条件相同时,一定判断一下次要条件。 Comparable是一个接口,用于强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序。 compareTo():比较此对象与指定对象的顺序。返回负数、零、整数。 ClassCastException:类型转换异常。 */ import java.util.*; //Comparable接口强制让学生具备比较性 class Student implements Comparable { private String name; private int age; Student(String name,int age) { this.name = name; this.age = age; } //复写compareTo() public int compareTo(Object obj) { if(!(obj instanceof Student)) throw new RuntimeException("不是学生对象"); Student s = (Student)obj; System.out.println(this.name+"...compareto..."+s.name); int temp = this.age-s.age; //有具体返回值可以用三元运算符,年龄相同,再按名字排。 return temp==0?this.name.compareTo(s.name):temp; } public String getName() { return name; } public int getAge() { return age; } } class TreeSetDemo { public static void main(String[] args) { TreeSet ts = new TreeSet(); //所存元素必须具备比较性, TreeSet()才能排序。 ts.add(new Student("lisi02",22)); ts.add(new Student("lisi04",20)); ts.add(new Student("lisi02",19)); ts.add(new Student("lisi01",20)); for(Iterator it = ts.iterator();it.hasNext();) { Student stu = (Student)it.next();//向下转型。 System.out.println(stu.getName()+"..."+stu.getAge()); } } }运行结果:
b 自定义比较器。让集合自身具备比较性:定义一个类,实现Comparator接口,覆盖compare方法。将该类对象
作为参数传递给TreeSet集合的构造函数。这种方法适用于:元素自身不具备比较性或不具备自己所需的比较性。
当两种方式都存在时,以比较器为主。
/* 练习:按照字符串长度排序。 自定义比较器:元素自身不具备比较性或不具备自己所需的比较性。 */ 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("z"); ts.add("hahhaha"); for(Iterator it = ts.iterator();it.hasNext();) { System.out.println(it.next()); } } } //实现Comparator接口,覆盖compare方法。 class StrLenComparator implements Comparator { public int compare(Object o1,Object o2) { String s1 = (String)o1; String s2 = (String)o2; //String类的compareTo方法 int num =new Integer(s1.length()).compareTo(new Integer(s2.length())); if(num==0) //主要条件符合,判断次要条件 return s1.compareTo(s2); return num; } }运行结果:
相关文章推荐
- 黑马程序员——java基础---集合(下)
- ——黑马程序员——OC加强部分 内存管理
- 继《一次体验很不爽的面试经历》后深入反思
- P140、面试题24:二叉搜索树的后序遍历序列
- P137、面试题23:从上往下打印二叉树
- 面试总汇二
- 面试书籍笔记
- android面试题笔试题总结
- 黑马程序员——集合类(二)
- PHP程序员 新人求职 平台
- 程序员要避开哪些坑
- 程序员技术练级攻略
- 月薪3万的程序员都避开了哪些坑
- 面试问答
- 月薪3万的程序员都避开了哪些坑
- 程序员们 你们是这样设置密码的吗?
- 黑马程序员——多线程
- 黑马程序员——java基础---集合(上)
- 疯狂Java程序员16堂课-----第4章:Java 内存管理之---Java引用种类
- ——黑马程序员——OC中构造和重写构造方法