复习
数据结构
栈结构: 进栈的方式:压栈 出栈的方式:弹栈
先进后出: 类似于子弹弹夹
队列:先进先出
又一个出口一个入口. 先来先出
当数据结构是数组的情况:
通过角标进行定位
需求:在当前x一个数组元素后添加一个元素
1. 定义一个新的数组,长度为原数组+1
2. 判断,看是否有x元素
X元素之前的:将前面的位置对应的元素添加新数组中
刚好是x:继续存储
X元素之后的:将后面的数组长度-1存储到新数组中
对于数据结构是数组的特点
查询快 增删慢(需要判断很多的条件)
链表结构:由很多链子将很多节点链接起来
每一个节点(数据):数据域(值)和指针域
一个节点内有自己特定的地址值 里面有自己的存储值还有指向的下一个数据域地址值
当需要查找一个元素是: 对于链接列表来说 从头开始查找指针域.以此来查询
特点 查询慢(从头开始查找)
增删快
当需要在x节点后插入一个节点 将x元素对应的指针域用temp来记录.
插入的y元素有自己的指针域 将y对应的指针域和它进行交换.
指向y元素 y元素的指针域再指向原本的下一个元素
当删除元素是 直接将前面的一个元素指向下一个. 将中间的移除.
List集合的子实现类特点:
ArrayList 为List接口(可变数组的)的子实现类,实现不同步.
底层数据结构是数组的形势,满足数组的特点.与数组的特点一直.查询快.增删慢
从线程安全问题来看:实现是不同步.因此是不安全的. 因此执行效率高.
Vector:可增长的对象数组,可以使用整数索引访问的组件.查询快.增删慢
从线程安全问题来看:实现是同步的,安全,因此效率低. 可以保证防止出现死锁的现象.
LinkedList:此实现是不同步的, 底层数据结构是连接链表. 特点.增删快,查询慢
在多线程中,只要线程不安全的类,都不回去使用.要使用安全的类.
安全的类 例如:
StringBuffer verson<E> hashtable<K,V >
synchronizedList: 返回值指定列表支持的同步(线程安全)列表
在里面调用
Synchronized (同步锁对象).
一般默认采用ArrayList(效率高,速率快) 多线程采用Verson.
ArrayList:
底层数据结构是数组的形式,满足数组的特点:查询快,增删慢.
从线程安全问题来看:线程不安全的,不同步,执行效率高
ArrayList是List的子实现类,因此元素可以重复:并且存取一致.
用ArrayList1存储对象 输出:
Eg: public class ArrayDemo1 {
public static void main(String[] args) {
ArrayList array=new ArrayList();
array.add("hello");
array.add("hello");
array.add("world");
array.add("world");
array.add("beauty");
array.add("java");
Iterator it=array.iterator();
while(it.hasNext()){
String s=(String)it.next();
System.out.println(s);
}
}
}
ArrayList存储自定义对象并进行遍历
Eg:1.建立学生对象.
3. 自定义对象,集合添加元素,迭代器遍历
//注意知道自己的类型是什么.j ava.lang.ClassCastException 转换类型不一致的时异常
Eg: public class ArrayListDemo2 {
public static void main(String[] args) {
ArrayList array=new ArrayList();
Student s1=new Student("钢铁侠",32);
Student s2=new Student("绿巨人",30);
Student s3=new Student("闪电侠",22);
Student s4=new Student("鹰眼",28);
array.add(s1);
array.add(s2);
array.add(s3);
array.add(s4);
Iterator it=array.iterator();
while(it.hasNext()){
Student s=(Student)it.next();
System.out.println(s.getName()+"--"+s.getAge());
}
}
}
Verson集合:底层是数组形式, 查询快,增删慢
从线程角度看:线程安全的类,同步,执行效率低
Verson()构造一个空间量默认的数组大小为10.
使用addElement来添加元素
public void addElement():添加功能 相当于add方法.
publicsynchronized void addElement(): 有同步代码块 转换到方法.
publicEnumeration<E> elements():获取元素. 相当于Iteratoriterator() ;
Synchronized可以保证线程安全.
Eg:
public class VectorDemo {
public static void main(String[] args) {
Vector v=new Vector();
v.addElement("Verson");
v.addElement("ArrayList");
v.addElement("List");
v.addElement("Collection");
v.addElement("Java");
//枚举向量的组件
Enumeration en=v.elements();
while(en.hasMoreElements()){
String s=(String)en.nextElement();
System.out.println(s);
}
}
}
LinkedList: 底层数据结构是链接列表,特点:查询慢,增删快
从线程角度看:线程不安全的一个类,不同步,执行效率高
特有功能:
添加 : public voidaddFirst(E e)将指定元素插入此列表的开头。
public void addLast(E e)将指定元素添加到此列表的结尾。
获取: public Object getFirst()返回此列表的第一个元素
public Object getLast()返回此列表的最后一个元素。
删除: public Object removeFirst()移除并返回此列表的第一个元素。
public Object removeLast()移除并返回此列表的最后一个元素。
Eg:
public static void main(String[] args) {
LinkedList link=new LinkedList();
link.addFirst("hello");//插入开头
link.addFirst("Link");
link.addFirst("List");
link.addLast("Java"); //加到结尾
Object obj=link.getFirst();
Object obj2=link.getLast(); //获取第一个和最后一个元素
移除并返回第一个元素
System.out.println("removeFirst:"+link.removeFirst());
}
}
练习题:ArrayList去除集合中的字符串的重复元素.
public class ArrayListText {
public static void main(String[] args) {
ArrayList array=new ArrayList();
array.add("RNG");
array.add("EDG");
array.add("RNG");
array.add("WE");
ArrayList newarray =new ArrayList();
Iterator it=array.iterator();
while(it.hasNext()){
Strings=(String)it.next();
if(!newarray.contains(s)){
newarray.add(s);
}
}
Iterator it2=newarray.iterator();
while(it2.hasNext()){
Strings=(String)it2.next();
System.out.println(s);
}
}
}
ArrayList去除集合中字符串的重复元素,附加条件:不能创建新集合.
由选择排序开始:从0索引对应的元素以此和后面对应的索引进行比较.
继续…
for循环嵌套 比较 如果重复 使用remove方法.
Eg:
import java.util.ArrayList;
import java.util.Iterator;
public class ArrayListDemo {
public static void main(String[] args) {
ArrayList array=new ArrayList();
array.add("RNG");
array.add("EDG");
array.add("RNG");
array.add("WE");
array.add("WE");
for(int x=0;x<array.size()-1;x++){
for(inty=x+1;y<array.size();y++){
if(array.get(x).equals(array.get(y))){
array.remove(y);
y--;
}
}
}
Iterator it=array.iterator();
while(it.hasNext()){
Strings=(String) it.next();
System.out.println(s);
}
}
}
输出结果:
RNG
EDG
WE
ArrayList去除集合中自定义对象的重复值(对象的成员变量值都相同)
当使用创建新集合是,用contain()方法比较,发现没有去除掉.
Contains()底层依赖于equals()方法,该方法默认比较的是对象的地址值.
必须重写Object的equlas()方法 才能比较成员变量的值是否相同.
首先在Student类中重写equals放法:
Eg: public class ArrayListText3 {
public static void main(String[] args) {
ArrayList array=new ArrayList();
Student s1 = new Student("罗斯", 30) ;
Student s2 = new Student("猎人", 22) ;
Student s3 = new Student("法师", 26) ;
Student s4= new Student("法师",26);
Student s5= new Student("法师",26);
Student s6= new Student("法师",26);
Student s7 = new Student("猎人", 22) ;
array.add(s1);
array.add(s2);
array.add(s3);
array.add(s4);
array.add(s5);
array.add(s6);
array.add(s7);
ArrayList newArray = new ArrayList() ;
Iterator it = array.iterator() ;
while(it.hasNext()){
Student s = (Student) it.next() ;
if(!newArray.contains(s)){
newArray.add(s) ;
}
}
Iterator it2 = newArray.iterator() ;
while(it2.hasNext()){
Student s = (Student) it2.next() ;
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
泛型:
使用ArrayList存储元素:
给ArrayList集合存储一些元素,String类型的元素,Integer类型的元素.
当给ArrayList类型存储元素时,存储不同元素的 当通过迭代器遍历时,编译不会出错.
运行出错 使用string类型接受,会出现 : ClassCastException 类转换异常
当定义一个数组时:字符串数组.
数组设计这样好处:提取告诉开发者,这里装String类型的元素.Java根据数组特点.
泛型的使用引用出来
格式<引用类型>:泛型只能放引用类型.
泛型的好处:
1. 将运行时期异常提前到编译时期
2. 解决了黄色警告线异常
3. 在获取数据时,不需要进行强制转换.
泛型可以应用在类上,接口上,方法上
在集合中使用比较多..
Eg:<String>类型:
Eg:
import java.util.ArrayList;
import java.util.Iterator;
public class GenericDemo2 {
public static void main(String[] args) {
ArrayList<String> array=new ArrayList<String>();
array.add("javase");
array.add("javaweb");
array.add("javaee");
//获取迭代器对象
Iterator <String>it=array.iterator();
while(it.hasNext()){
Strings=it.next();
System.out.println(s);
}
}
}
使用ArrayList集合存储自定义对象并进行遍历
Eg:
public class GenericDemo3 {
public static void main(String[] args) {
ArrayList<Student>array=new <Student>ArrayList();
Student s1=new Student("金刚狼",28);
Student s2=new Student("万磁王",26);
Student s3=new Student("教授",45);
Student s4=new Student("冰男",25);
array.add(s1);
array.add(s2);
array.add(s3);
array.add(s4);
Iterator<Student> it=array.iterator();
while(it.hasNext()){
Student s=it.next();
System.out.println(s.getName()+"--"+s.getAge());
}
}
}
输出结果:
金刚狼--28
万磁王--26
教授--45
冰男—25
泛型可以提供程序的安全性!
早期时候:用Object类型代替任意的类型
向上转型是不会出现异常
但是向下转型的时候,由于隐藏了类型转换,导致出现错误!(需要知道自己需要的类型)
Eg:
public class ObjectToolDemo {
public static void main(String[]args) {
ObjectTool ot=new ObjectTool();
ot.setObj(27);//Object类型
Integer i=(Integer)ot.getObj();//向下转型
System.out.println("年龄是"+i);
ObjectTool ot2 = new ObjectTool() ;
ot2.setObj("龙哥");
String str = (String) ot2.getObj() ;//向下转型
System.out.println("姓名是:"+str);
}
}
将泛型定义在类上: 解决不安全的错误.
在开发中根据具体类型在测试中书写
类:
public class ObjectTool<T> {
private T obj;
public void setObj(T obj){
this.obj=obj;
}
public T getObj(){
return obj;
}
}
测试类:
public class ObjectToolDemo {
public static void main(String[] args) {
ObjectTool<String> str=new ObjectTool<String>();
str.setObj("龙哥");
// Integer i=str.getObj(); //类型不匹配
String name=str.getObj();
System.out.println("姓名是:"+name);
ObjectTool<Integer> str2=new ObjectTool<Integer>();
str2.setObj(20);
Integer i=str2.getObj();
System.out.println("年龄是"+i);
}
}
输出结果:
姓名是:龙哥
年龄是20
泛型定义在方法上:调用方便,不需要定义多个重载方法,一个级可以返回多个类型
定义在方法上:
public class ObjectTool{
public <T>void show(T t){
System.out.println(t);
}
}
测试类:
public class ObjectToolDemo {
public static void main(String[] args) {
ObjectTool ot=new ObjectTool();
ot.show("javase");
ot.show(true);
ot.show(20);
}
}
输出结果:
javase
true
20
泛型定义在接口上:
接口:
public interface Inter<T> {
public abstract void show(T t);
}
接口的子实现类:
public class InterImpl<T> implements Inter<T>{
//子实现类
@Override
public void show(T t) {
System.out.println(t);
}
}
测试类:
public class InterDemo {
public static void main(String[] args) {
//第一种状况
//接口加入泛型:接口的子实现类已经知道传递了是什么数据类型
Inter<String> i=new InterImpl<String>();
i.show("Javase");
i.show("javaweb");
//第二种状况
// 接口的子实现类在实现接口的时候,不知道具体的数据类型是什么
//在测试类的时候,传入具体数据类型
Inter<Integer>i2=new InterImpl<Integer>();
i2.show(27);
Inter<String> i3=new InterImpl<String>();
i3.show("小虎");
}
}
输出结果:
Javase
javaweb
27
小虎
泛型的高级:通配符
任意类型<?> <? Extends E>:向下限定,E类型以及E类型的子类
<? Super E>:向上限定,E类型以及E类型的父类
import java.util.ArrayList;
import java.util.Collection;
public class GenericDemo1 {
public static void main(String[] args) {
//创建Collection集合的对象,前后数据类型保持一致
//Collection<Object> c1 = newArrayList<Animal>() ;
//Collection<Object> c3 = newArrayList<Dog>() ;
//会报错因为前后的数据类型不一致
Collection<Object> c1=new ArrayList<Object>();
// <?> :可以是任意类型,包括Object类型以及任意的Java类
Collection<?> c4 = new ArrayList<Object>() ;
Collection<?> c5 = new ArrayList<Animal>() ;
Collection<?> c6 = new ArrayList<Cat>() ;
//<? extends E>:向下限定,E类型以及E类型的子类
Collection<? extends Object> c8 = new ArrayList<Object>() ;
Collection<? extends Object> c11 = new ArrayList<Cat>() ;
//<? super E>:向上限定,E类型以及E类型的父类
Collection<? super Animal> c12 = new ArrayList<Object>() ;
Collection<? super Cat> c13=new ArrayList<Animal>();
}
class Animal{
}
class Cat extends Animal{
}
class Dog extends Animal{
}
}
Jdk5以后提供了很多特性:泛型,增强for循环,可变参数,静态导入,自动拆装箱,枚举等
增强for循环 书写格式
for(集合或者数组中数据类型 变量名:集合或者数组的对象名){
输出变量名
}
增强for循环的弊端:
遍历数组或者集合时候,数组对象或者集合对象不能为Null
否则出现空指针异常.
如果对象为空,加上非空判断
增强for循环的出现就是为了替代迭代器遍历集合,以后开发中使用增强for遍历元素
Eg:
import java.util.ArrayList;
public class forDemo {
public static void main(String[] args) {
int []arr ={12,22,5,23,263,23};
//普通for循环遍历
for(int x=0;x<arr.length;x++){
System.out.print(arr[x]+"");
}
System.out.println("");
//使用增强for遍历
for(int i :arr){
System.out.print(i+" ");
}
System.out.println("");
String []strArray ={"Javase","JavaWeb","JavaEE"};
for(String s:strArray){
System.out.println(s);
}
System.out.println("----------");
for(String s:strArray){
System.out.println(s);
}
ArrayList<String>array =new ArrayList<String>();
array.add("JavaSE");
array.add("JavaWeb");
array.add("JavaEE");
//当数组为空时:增强for遍历会出现空指针异常
}
}
输出结果:
12 22 5 23 263 23
12 22 5 23 263 23
Javase
JavaWeb
JavaEE
----------
Javase
JavaWeb
JavaEE
当使用该方法添加元素时,出现ConcurrentModificationException异常
//使用增强for遍历该集合
for(Strings :array){
//获取到每一个元素
//java.util.ConcurrentModificationException
判断当前集合中是否有"world",如果有就添加元素
if("world".equals(s)){
array.add("javaee");
}
}
增强for循环是为了替代迭代器:
代码简单,开发中经常使用.
使用ArrayList集合存储自定义对象并遍历
方式:
1. toArray()
2. Collection集合的迭代器: Iterator iterator();
3. List集合的迭代器:ListIterator listiterator();
4. 普通for循环:size()和get(int index)相结合
5. 增强for循环
Eg:
import java.util.ArrayList;
import java.util.Iterator;
public class ForText1 {
public static void main(String[] args) {
// 创建ArrayList集合
ArrayList<Student> array = new ArrayList<Student>();
Student s1=new Student("钢铁侠",29);
Student s2=new Student("鹰眼",26);
Student s3=new Student("绿巨人",31);
Student s4=new Student("猪猪侠",7);
array.add(s1);
array.add(s2);
array.add(s3);
array.add(s4);
//普通for循环:size和get(intindex)方法结合
for(int x =0 ; x < array.size() ; x ++){
Student s = array.get(x) ;
System.out.println(s.getName()+"---"+s.getAge());
}
//Collection集合的迭代器:Iterator iterator();
Iterator<Student> it =array.iterator() ;
while(it.hasNext()){
Student s = it.next() ;
System.out.println(s.getName()+"----"+s.getAge());
}
//增强for循环
for(Student s : array){
System.out.println(s.getName()+"----"+s.getAge());
}
}
}
上周作业题:
ArrayList<Student>不止一个
大的集合:ArrayList<ArrayList<Student>>
集合的嵌套遍历.
首先建一个学生类:
Eg:
import java.util.ArrayList;
public class ArrayListText {
public static void main(String[] args) {
//大集合对象
ArrayList<ArrayList<Student>> bigArray=newArrayList<ArrayList<Student>>();
//第一个子集合对象
ArrayList<Student>firstArray=new ArrayList<Student>();
Student s1=new Student("钢铁侠",32);
Student s2=new Student("美国队长",28);
Student s3=new Student("鹰眼",26);
firstArray.add(s1);
firstArray.add(s2);
firstArray.add(s3);
bigArray.add(firstArray);//将第一个小集合添加到大集合里面
ArrayList<Student>secondArray=new ArrayList<Student>();
Student s4=new Student("金刚狼",34);
Student s5=new Student("风暴女",26);
Student s6=new Student("火男",32);
secondArray.add(s4);
secondArray.add(s5);
secondArray.add(s6);
bigArray.add(secondArray);
ArrayList<Student>thirdArray=new ArrayList<Student>();
Student s7=new Student("索隆",24);
Student s8=new Student("娜美",20);
Student s9=new Student("乌索普",23);
thirdArray.add(s7);
thirdArray.add(s8);
thirdArray.add(s9);
bigArray.add(thirdArray);
//增强for遍历
//大集合:ArrayList<ArrayList<Student>>
for(ArrayList<Student> array:bigArray){
//子集合:ArrayList<Student>
for(Student s:array){
System.out.println(s.getName()+"--"+s.getAge());
}
}
}
}
输出结果:
钢铁侠--32
美国队长--28
鹰眼--26
金刚狼--34
风暴女--26
火男--32
索隆--24
娜美--20
乌索普--23