多态:允许将子类对象的地址赋值给父类对象,从而实现接口的多种实现方式
(针对对象)集合的由来:
我们学习的是面向对象编程,而面向对象语言对事务的表现 是通过对象来体现的,为了方便管理对多个对象
进行操作,我们就将将这多个对象存储到一个容器当中,在 我们目前所有学的知识体现当中,基础到的容器只有数组
和StringBuffer,但是呢?StringBuffer的结果是一个字符 串,不能满足存储对象的要求,所以我们只能用数组,但是 数组的长度是固定的,不可能满足我们灵活多变的需求,这 个时候,为了适应程序的开发,Java提供了一种技术。
这种技术叫做:集合
集合和数组的区别:
1.长度区别
数组的长度是固定
集合的长度是可变的(自动增减长度)
2.内容区别
数组只能存储同一种数据类型的元素
集合存储不同数据类型的元素(通常不存基类型)
3.类型区别
数组既能够存储基本数据类型,也能够存储引用 数据类型
集合只能存储引用数据类型
Collection:
Collection:是集合类的顶层接口,他的子体系是有重复的、 有唯一的、有排序的、有无序的。
注:
1.Collection是接口,只能通过创建其子类对象来实现。
2.用子类对象去实例化父类的对象,父类的对象会去父类 找,如果子类有方法重写,执行子类的方法。如果父类没有 此方法,则会报错,这就是多态!!(建议用子类的对象去 实例化子类对象,因为子类找不到会去父类找, 这样子功能 就会多很多)
3.类用继承 接口用实现
Collection的功能:
添加功能:
.add(Object obj):添加一个元素
c.addAll(Collection c):添加一个整个集合的元素(放 的一个集合对象)
注:
Object类是所有引用类型的老祖宗
Collection是ArrayLis的老祖宗
父类对象可以接收任何子类对象(向上转型)
但是需要用到自雷的时候,记得向下转型(强转)
删除功能:
c.clear();清除集合当中的所有元素
c.remove(Object obj):移除指定元素
c.removeAll(Collection c):移除指定集合元素
判断功能:
c.contains(Object obj):判断集合中是否存在某 个元素
c.containsAll(Collection c):判断集合当中是 否存储了指定的集合
注:
1.contains()只能判断是否有这个对象,不能判 断类内的成员变量
获取功能:
Interface Iterator<E>(重点)
长度获取
c.size() 获取集合长度
面试题:数组有么有length()方法?字符串有么有 length方法()?集合当中有没有length方法?
注:
1.StringBuffer中,capacity():返回的是总容 量,length():返回当前已用长度
2.数组没有length()方法,其长度有.length 成员变量来返回
String有.length()方法,因为字符串本身 就是一个类
虽然ArrayList也是一个类,但是其 用.size()返回长度
交集功能:
boolean retainAll(Collection c):两个集 合,保留进行交集的元素值
注:
此方法是毁掉自己的,传进来的集合不会发生改 变,但是调用此方法的集合将会只剩下两集合的 交集
举例:
ArrayList c = new ArrayList();
c.add("hello");
c.add('a');
c.add(1);
c.add(true);
ArrayList c2 = new ArrayList();
c2.add("hello");
c.retainAll(c2);
System.out.println(c);//[hello]
将集合转换为数组:
Object [] obj = (Object[])c.toArray();
需进行类型转换,因为这时候保证转换类型正确 (因为在ArrayList类型中跳出来,可能需要类型 转化)
注:
数组:syso(arr) 打出来的是一个地址
列表:syso(list) 打出来的是一个[]集合
Collection迭器:(Iterator)
因为迭代器是一个接口 所以不能实例化
//如果需要实例化则需要通过具体实现子类来完成
//而我们的集合就正好有迭代器的具体对象返回 c.iterator(); (Collection的迭代器)
举例:
Iterator it = c.iterator();
//我们现在使用的循环次数是不确定,所以it.hasNext()可 以判断你这个迭代器里面是不是有更多元素
//如果有,就返回true 没有了就不用进行循环 返回的是 false
while(it.hasNext()) {
//it.next();可以获取迭代器里面的下一个具体元素
//获取的是一个对象的具体地址值 将这个地址值赋值给对应 类型进行接收即可
Student s = (Student)it.next();
System.out.println(s.getAdd());
}
List(Collection的下一级):
list集合的特点: (接口)
有序的(存储的顺序和取出的顺序是一致的),可重复
仿造数组来做的,但不是数组(有索引)
List的特有功能:(可以用Collection的功能)
1.添加功能
void add(int index, E element):在列表中指定的位 置上插入指定的元素(可选操作)。
2.获取功能
Object get(int index):返回此列表中指定位置的元 素。
3.列表迭代器
ListIterator():列表迭代器,很少使用
4.删除功能
Object remove(int index):根据指定索引删除元素
5.修改功能
Object set(int index,Object e):根据指定索引替换 指定内容
举例:
List list = new ArrayList();
list.add("hello");
list.add("java");
list.add(1,"python");
list.add(2,".NET");
list.set(1, "JAVAEE");
注: list.add(15,"GO");//有问题,如果需要插入元素 需 要确定存在该元素
List迭代器:(ListIterator)
每一层都有自己的迭代器,都不能实例化,只能 通过对象的方法返回元素的迭代器
举例:
ListIterator it = list.listIterator();
while (it.hasNext()) {
String s= (String) it.next();//获取第一个
System.out.println(s);}
注:
1.hasNext():返回 true还有元素(不为空)
2.next():返回迭代中的下一个元素。(刚开始为-1)
3.如果不知道什么类型可以先创建一个Object obj来 接收列表返回的元素,然后在用的时候在进行强转 (很多函数的参数都是Object:可以接收任何类;父 类,可以接收其任何子类)
举例:
//List 三种遍历方式
ListIterator lit = list.listIterator();
//ListIterator 接口 listIterator() 方法
while (lit.hasNext()) {
String s = (String) lit.next();
System.out.println(s);
}
for (int i = 0; i < list.size(); i++) {
String s = (String)list.get(i);
System.out.println(s);
}
//增强循环
for(Object obj :list) {
System.out.println((String)obj);
}
注:迭代器是接口,需要用当前对象的方法返回
ArrayList:(Collection小儿子)
功能最全,可以使用以上两个接口的所有功能,并且其是个 类,可以实例化,可以创建对象
添加功能:
addFirst(E e):在此列表的开始处插入指定的元素。
addLast(E e):在此列表的结束处插入指定的元素。
getFirst():返回此列表中的第一个元素。
getLast():返回此列表中的最后一个元素。
举例:
ArrayList去除集合当中的重复元素(不能创建新的集合)
ArrayList array = new ArrayList();
array.add("php");
array.add("java");
array.add("java");
array.add("java");
array.add("php");
array.add("Python");
array.add("java");
array.add("C++");
array.add("Python");
array.add("C++");
array.add("C#");
for(int x = 0;x < array.size()-1;x++) {
for(int y = x + 1;y < array.size();y++) {
if(array.get(x).equals(array.get(y))) {
array.remove(y);
y--;
}
}
}
注:
1..remove()后,ArrayList的所有元素都会往前推一个, 如果不b--,刚刚remove()的位置上的重复元素就去不掉
2.ArrayList 没有迭代器,其遍历用数组的方式
for (int i = 0; i < newArray.size(); i++) {
Student s = (Student)newArray.get(i);
}
补充:
1.Collection(接口)->List(接口)->ArrayList(对象)
2.前面两个需要靠子类对象来实现
3.Collection与List 都有迭代器,ArrayList没有
4.Iterator(Collection迭代器),ListIterator(List的 迭代器)。迭代器都是接口。他们都需要子类对象的方法 来返回一个迭代器来实现:Iterator it = c.iterator();
5.
ArrayList:
底层的数据结构为数组,查询快 增删慢
线程不安全,效率高
LinkedList:
底层的数据结构为链表,查询慢,增删快
线程不安全,效率高
Vector:
底层数据接口是数组,查询快 增删慢
线程安全,效率低
List的三个儿子,我们一般使用谁?
查询多:ArrayList
要安全吗:Vector(即使安全也不用 因为被淘汰)
如果懒得选,就直接用ArrayList 其余几个很少用到
注:
数组因为有索引,所以查询快,但是增删会导致后面元素顺 序乱套,所以查询快,增删慢
链表因为靠指针,所以查询慢,但是增删会只需在某个位置 重新建立起节点的链接就行,其他元素都不用动,所以查询 慢,增删快
6.在每个类中都可以重写.equal()方法,直接针对该类对象 (就像C++中的函数重载)
举例:
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null){
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
注:
String 类型 equal是比较类型
ArrayList类型 equal是比较元素的地址
类的equal方法重写在eclipse的工具栏上有