02_Java面向对象

面对对象程序设计(Object-oriented Programming,OOP)

抽象过程:底层机器>汇编语言(对底层机器的轻微抽象)>C/BASIC命令式语言(对汇编的抽象)

问题空间>>编程语言(面向过程/面向对象)>>解空间(机器模型)

Smalltalk面向对象语言五个特性

万物皆对象:将对象视为奇特的变量,存储数据

程序是对象的集合,它们通过发送消息来告知彼此所要做的

每个对象都有自己的由其他对象所构成的存储

每个对象都拥有其类型:类class

某一特定类型的所有对象都可以接收同样的消息:多态

对象object(具体:描述客观事物的实体)-(抽象:具有相同属性和方法的一组对象的集合)

类是多个对象进行综合抽象的结果,是实体对象的概念模型,而一个对象是一个类的实例。类定义了对象拥有的特征(属性)和行为(方法)

所有Java程序都以类class为组织单元

面向对象三大特征封装encapsulation、继承inheritance、多态polymorphism

:关键词class定义自定义的数据类型(引用数据类型)

    [访问修饰符class 类名{ //帕斯卡命名规则(类名首字母大写)

     //类成员

属性--成员变量

        方法--成员方法

    }

属性:对象所拥有的特征在类中的表示

[访问修饰符] 数据类型 属性名;

方法:对象执行操作的行为(返回值|方法名|参数|方法体)

[访问修饰符] 返回类型|void 方法名称(参数类型 参数){//参数列表-形参

     //方法体

     [return 返回值;]

}

创建对象:类名 对象名=new 类名();//左边类名为对象数据类型,右边类名()为类的构造方法

使用对象:对象名.属性//引用对象的属性

          对象名.方法名();//引用对象的方法

          返回值类型 变量名=对象名.方法名(实参);

方法调用:直接调用;new对象调用

对象数组:每个数组元素就是一个对象,根据下标找到某个元素时,可以按照对象的使用方

法来使用该元素

成员变量(全局变量):直接在类中定义的变量,属于对象

成员方法

//带参数有返回值的方法

public String work(int time){

    return "...";

}

局部变量:定义在方法(包main方法)或结构语句中的变量

成员变量与局部变量的区别:

1.  应用范围:成员变量在整个类内都有效、局部变量只在其声明的方法内有效

2.  生命周期:成员变量属于对象,随着对象的创建而创建,随着对象的消失而消失

局部变量使用完马上释放空间

3.  存储位置:成员变量属于对象,存储在堆内,堆内的实体,当没有引用指向其时,才垃圾回收清理

局部变量存在栈内存中,当不在使用时,马上就会被释放。

4.  初始值:

成员变量它存储在堆中,如果没有赋初值,有默认值

1.  整数byte、short、int、long =0;

2.  char='\uoooo';

3.  boolean =flase;

4.  String =null;

5.  类类型 =null;

6.  数组 =null;

局部变量,在栈内存中,必须给初始化值,必须手动初始化

内存分析:栈内存(存储引用)-堆内存(存储对象)

匿名对象:对象实体没有对应的变量名引用

new Car().run();//当对象对方法进行一次调用的时候使用匿名对象简化代码;

//可以将匿名对象作为实际参数传递进去

形参(形式参数:方法定义处参数)-实参(实际参数:方法调用处参数):数据类型、个数、顺序相同

方法传参:基本数据类型和引用数据类型内存分配和传参区别

1.基本数据类型传递的是值(拷贝),形参导致参数的变化与实参无关

2.引用数据类型传递的是地址,形参实参指向的是同一个对象,形参导致的变化影响实参

构造方法:默认构造方法、带参数的构造方法;主要作用是进行一些数据的初始化

//构造方法没有返回值;方法名与类名相同;手动编写构造方法会导致默认构造方法消失

[访问修饰符] 方法名([参数列表]){

  //方法体

}

public class Student{

public Student(){//默认的无参隐式构造方法:Student()创建对象的时候执行

      //代码

}

//手动编写带参构造方法:对属性进行初始化

  public Person(String name1, int age1, int weight1) {

      this.name = name1;

      this.age = age1;

      this.weight = weight1;

  }

}

Student s1=new Student(); //调用构造方法

Person p1=new Person(“小明”,18,60); //构造方法重载

this关键字:当前对象

this.属性|普通方法

本类构造方法的调用:this(参数)//必须放在第一句

super关键字:指向父类

super(参数);//调用父类构造方法

super.父类属性|方法

构造方法重载:方法参数类型、顺序必须不同,与返回值类型和方法体无关

方法重载:在同一个类中;方法名相同,方便记忆;参数的个数或类型不同

//无参数的工作方法

public void work(){

}

//带参数的工作方法--重载

public void work(String contect){

}

static关键字(修饰符):实例变量/静态变量-实例方法/静态方法

    内存分析:存储在方法区(静态数据共享区)

public class Person {

    public String name;//实例变量

    public static int age;//静态变量|类变量

    public static int PERSON_LIVE;

    public  void show1(String name,int age){//实例方法

        show2(name,age);//可以直接访问静态变量或方法

    }

    public static void show2(String name,int age){//静态方法|类方法

        //不能使用thissuper,不能直接访问实例变量或方法

        //实例方法,可以调用静态变量或方法、实例变量或方法,但不能定义静态变量

        System.out.println(name+age);

    }

}

public static void main(String[] args) {//main方法--静态方法

    Person p = new Person();

    p.age = 16;

    Person.PERSON_LIVE = 1;//类名.类成员

    Person.show("aaa", 16);//调用静态方法

}

static{//java虚拟机加载类时,就会执行该代码块

    //静态代码块,对类的初始化操作

}

封装:将类的状态信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。

/* 封装的步骤 */

//1.修改属性的可见性,设为private

    private int age;

    //2.设置setter/getter()方法:用于属性的读写

    public int getAge() {//age赋值

        return age;

    }

    public void setAge(int age) {//age

        //3.设置属性的存取限制:对属性值的合法性进行判断

        if(age < 0){

            System.out.println("不能小于0");

            return;

        }

        this.age = age;

    }

继承和多态

继承:代码重用;只支持单根继承,即一个类只能有一个直接父类;根类Obejct

[访问修饰符] class <SubClass> extends <SuperClass>{

    子类访问父类构造方法:super();super(name){

//继承条件下的构造方法:系统默认调用父类无参构造方法;子类构造方法通过

super显式调用父类的有参构造方法,执行父类相应构造方法,而不执行父类无

参构造方法

      //super代表父类对象;在子类构造方法中调用且必须是第一句;不可以访问

父类中定义为private的属性和方法

}

    子类访问父类属性:super.name

    子类访问父类方法:super.print();

} //SubClass子类或派生类,SuperClass父类或基类

方法重写(父子类):方法名相同、参数列表相同、返回值类型相同或者是其子类、访问权限不能严于父类、不能抛出比父类方法更多的异常

方法重写与方法重载的区别:

比较项

位置

方法名

参数列表

返回值

访问修饰符

方法重写

子类

相同

相同

相同或是其子类

不能比父类更严格

方法重载

同类

相同

不相同

无关

无关

多态:同一个引用类型,使用不同的实例,而执行不同操作(JVM的动态绑定机制:重写后的方法)

JVM的静态绑定:成员变量、静态方法

向上转型:父类ude引用指向子类对象,自动进行类型转换

    <父类型> <引用变量名>=new <子类型>();

    Pet pet=new Dog();

    pet.setHealth(20);//通过父类引用对象调用的方法是子类覆盖或继承父类的方

法;无法调用子类特有的方法

向下转型:将一个指向子类对象的父类引用赋给一个子类的引用(父类类型转换为子类类型);需强制转换

    <子类型> <引用变量名> = (<子类型>) <父类型的引用变量>;

    Dog dog=(Dog)pet;//pet转换为Dog类型

    dog.catchingFlyDisc();//执行Dog特有的方法

抽象类和接口

抽象方法

[访问修饰符] abstract <返回类型> <方法名>([参数列表]);

抽象类:被abstract修饰;不能实例化;可以创建一个引用变量,其类型是一个抽象类,指向非抽象的子类实例;没有方法体;一旦类中出现抽象内容,保证其子类必须对其进行重写,约束规范作用

定义抽象类:

    public abstract class 类名称{

    修饰符 abstract 返回类型 方法名();

    修饰符 返回类型 方法名(){

        //方法体

    }

接口:是一种能力,约定;没有构造方法,不能实例化的类型

定义接口:

public interface 接口名{

    //接口成员,只允许是全局常量和公共的抽象方法;不能实例化

    public static final value;//变量

public abstract void Method();//abstract可省略;默认public abstract

}

接口继承的语法:

    [修饰符] interface 接口名 extends 父接口1,父接口2,……{

        常量定义

        方法定义

}

类实现接口:

    public 类名 implements 接口1,接口2,…{//必须实现接口中定义的所有方法

        实现接口中方法

        普通方法

}

Paper paper = new A4Paper();//接口指向具体实现类的对象

包机制

声明包:package 包名;// java源文件中第一条非注释性语句,一个源文件只能有一个包声明语句;

导入包:import 包的完整路径 //每个包都是独立的,顶层包不会包含子包的类;package

和import的顺序是固定的

命名包:package com|edu|net|org.research(部门名). project(项目名);//小写字母

包机制:src/code-/com/hfxt/xxx;类文件的管理;将一组功能相同的类放在同一个包下

JDK提供的基本包:java.lang(虚拟机自动引入)、java.util(提供一些实用类)、java.io(输入、输出)、java.sql(访问数据源)

访问控制(访问修饰符):public(不同包)>protected(子类)>default(同包)>private(同类)

Jar:打包文件

    jar tvf test.jar 显示jar文件中包含的所有目录和文件名大小,详细信息

    jar xvf test.jar 解压test.jar到当前目录,显示详细信息

    jar tvf rt.jar > d:\rt.txt 重定向查看jar文件内容

模板设计

    abstract class Runcode{//模版代码修饰为final,避免子类重写父类的模版代码

    public final void Method(){

}

}

异常

java异常体系结构:所有异常类型都是Throwable类的子类,它派生两个子类:Error类和Exception类

Error:表示仅靠程序本身无法恢复的严重错误

Exception:由java应用程序抛出和处理的非严重错误; 异常层次结构的根类

运行时异常(RuntimeException及其子类)、Checked异常(非运行时异常)

    NullPointException            -- 空指针异常

    ClassNotFoundException       -- 不能加载所需的类

    ArrayIndexOutOfBoundException -- 数组下标越界

    InputMismatchException       -- 得到的数据类型与实际输入的不匹配

    IllegalArgumentException     -- 方法接收到非法参数

    ClassCastException           -- 对象强制类型转换出错

Java异常处理机制:五个关键字(trycatchfinallythrowthrows)

try-catch-finally捕获异常:

try{

  //执行可能产生异常的代码

}catch( Exception e){

  //捕获异常

}finally{

  //无论以上代码发生什么异常都会执行的操作

}

throws声明抛出异常:声明多个异常用逗号隔开

throw抛出异常:手动抛出异常

public static void divide() throws Exception{

throw new Exception(“描述信息”); //手动抛出并声明

}

自定义异常:JDK的异常类型不能满足程序需要

Java高级

集合框架和泛型

集合(对象容器):位于java.util包中,提供接口(虚线框)和实现类(实线框)

--|Collection: 单列集合;存储一组不唯一、无序的对象

---|List: 存储有序元素,可重复;存储一组不唯一、有序的对象

---|ArrayList: 数组实现, 查找快, 增删慢

---|LinkedList: 链表实现, 增删快, 查找慢

---|Vector: 数组实现, 但线程安全, 效率略低

---|Set: 存储无序元素,不可重复;存储一组唯一、无序的对象

---|HashSet

---|TreeSet

---|LinkedHashSet

--|Map: 键值对

---|HashMap:底层是哈希表数据结构,线程同步,不可以存入null键,null值,效率较低

---|TreeMap:底层是二叉树数据结构。可以对map集合中的键进行排序

---|HashTable:底层是哈希表数据结构,线程是不同步的,可以存入null键,null值

    ---|LinkedHashMap:

Collection接口>子接口:List(链表ArrayList|线性表LinkedList)-Set集(HashSet/ TreeSet)

/* Collection通用方法 */

增加:

add(Object) 将指定对象存储到容器中

addAll()        将指定集合中的元素添加到调用该方法和集合中

删除:

remove()        将指定的对象从集合中删除

removeAll()     将指定集合中的元素删除

修改:

clear()         清空集合中的所有元素

判断:

isEmpty()        判断集合是否为空

contains()       判断集合何中是否包含指定对象

containsAll()    判断集合中是否包含指定集合

equals()        判断两个对象是否相等 

获取:int size()     返回集合容器的大小

转成数组:toArray()   集合转换数组

List集合特有方法

增加:

void add(int index, E element)            指定位置添加元素

boolean addAll(int index, Collection c)   指定位置添加集合

删除:E remove(int index)        删除指定位置元素

修改:E set(int index,E element) 返回的是需要替换的集合中的元素

查找:注意IndexOutOfBoundsException异常、找不到返回-1

E get(int index)

int indexOf(Object o)

lastIndexOf(Object o)

求子集合:List<E> subList(int fromIndex, int toIndex) //不包含toIndex

ArrayList<E>:分配连续的存储空间的数组;遍历、随机访问元素效率高

boolean add(Object o)        列表末尾添加元素,起始索引位置从0开始

void add(int index,Object o) 指定索引位置添加元素

boolean contains(Object o)    判断列表中是否存在指定元素

boolean remove(Object o)      删除元素

int indexOf(Object obj)      返回元素在集合中出现的索引

LinkedList:链表存储方式;插入、删除元素效率高

数据结构:栈(先进后出:push()/pop())-队列(先进先出: offer()/poll())

void addFirst(Object o)      列表首部添加元素

void addLast(Object o)       列表末尾添加元素

Object getFirst()/getLast()   返回列表的第一个/最后一个元素

Object removeFirst()/removeLast() 删除并返回列表第一个/最后一个元素

descendingIterator()          返回逆序的迭代器对象

Vector:描述一个线程安全的ArrayList

    void addElement(E obj)  在集合末尾添加元素

    E elementAt( int index) 返回指定角标的元素

    Enumeration elements()  返回集合中的所有元素,封装到Enumeration对象中

    Enumeration 接口:

  boolean hasMoreElements() 测试此枚举是否包含更多的元素。

  E nextElement()    如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素

Iterator接口(迭代器):Itreable> Collection

Iterator<T> iterator()返回该集合的迭代器对象

boolean hasNext()        判断是否存在另一个可访问的元素

E next()                 返回要访问的下一个元素

void remove()           移除迭代器返回的最后一个元素

List特有迭代器ListIterator(extends Iterator)

ListIterator<E> listIterator()

add(E e)         将指定的元素插入列表

void set(E o)   用指定元素替换next或previous返回的最后一个元素

hasPrevious()    逆向遍历列表,列表迭代器有多个元素,则返回 true

previous()       返回列表中的前一个元素

遍历集合:for循环;forEach;迭代器Iterator

//方法一:for循环

for(int i = 0;i < list.size();i++){

  System.out.println(NewsTitle)list.get(i).getId());

}

//方法二:增强for

for(Object obj : list){

  System.out.println(((NewsTitle)obj).getId());

}

//方法三:使用迭代器Iterator

Iterator iterator = list.iterator();

while(iterator.hasNext()){

  Object obj = iterator.next();

  System.out.println(((NewsTitle)obj).getId());//强制转换

}

Set接口:HashSet(hash表)-TreeSet(红-黑树)

    HashSet(线程不安全,存取速度快。底层是以实现的)

HashSet检测重复:hashcode()和equals方法

TreeSet:红-黑树的数据结构,默认对元素进行自然排序

-黑树:自平衡二叉查找树

http://images.cnitblog.com/i/497634/201403/251730074203156.jpg

    红黑树基本操作(添加/删除):左旋-右旋

http://images.cnitblog.com/i/497634/201403/251733282013849.jpg  http://images.cnitblog.com/i/497634/201403/251735527958942.jpg

Map接口:存储一组键-值对(键集-值集),提供key到value(k-v)的映射

Hashtable-HashMap-TreeMap-LinkedHashMap

Map常见方法:

添加:V put(K key, V value)       可以是相同的key值,添加的value值会覆盖

putAll(Map<? extends K,? extends V> m)  从指定映射中将所有映射关系复制到此映射中

删除:remove()    删除关联对象,指定key对象

clear()     清空集合对象

获取:value get(key) 判断键是否存在的情况。当指定的键不存在返回null

判断:boolean isEmpty()               长度为0返回true否则false

boolean containsKey(Object key)    判断集合中是否包含指定的key

boolean containsValue(Object value) 判断集合中是否包含指定的value

长度:int size()

遍历Map:

Set<K> keySet()        返回所有的key对象的Set集合, 再通过get方法获取键对应的值

Collection<V> values() 获取所有的值,不能获取到key对象

Set<Map.Entry<k,v>> entrySet()  //map 集合中的键值映射关系打包成对象,Map.Entry对象的getKeygetValue获取其键和值

泛型Generic:把对象的类型作为参数,指定到其他类或方法上,从而保证类型转换的安全性和稳定性;可以约束集合内的元素类型

    <T>  指定容器中元素的类型T(引用类型)

    集合类<类类型> 变量名=new 集合类<类类型>();

    泛型方法:public <泛型声明> 返回值类型 函数名(泛型 变量名)

             public <T> T getT(T t) {}

    泛型类:修饰符 class 类名<泛型>

           pubic class Demo<T> {}

    泛型接口:public interface Inter<T> {}

工具类(静态方法):Arrays(操作数组类)-Collections(操作集合类)

Arrays类:

binarySearch(int[])/binarySearch(double[]) 二分查找(数组需要有序)

void sort(int[])/sort(char[]) 数组排序

String toString(int[]) 数组转为字符串

copyOf()                复制数组

copyOfRange()            复制部分数组

equals(int[],int[])     比较两个数组是否相同。

List asList(T[]);        将数组变成集合

Collections类:

二分查找:

int binarySearch(list,key);

int binarySearch(list,key,Comparator); list 集合中的元素都是Comparable 的子类

排序:

sort(list); //实际使用list对象的compareTo方法

sort(list,comaprator); //按照指定比较器进行排序

取集合最大值或者最小值

max(Collection)/max(Collection,comparator)

min(Collection)/min(Collection,comparator)

对list集合进行反转:reverse(list);

对比较方式进行强行逆转:Comparator reverseOrder()/Comparator reverseOrder(Comparator);

对list集合中的元素进行位置的置换:swap(list,x,y);

对list集合进行元素的替换:replaceAll(list,old,new);

可以将不同步的集合变成同步的集合:

Set synchronizedSet(Set<T> s)

Map synchronizedMap(Map<K,V> m)

List synchronizedList(List<T> list)

集合变数组: Collection 的toArray()方法

实用类

Java API:Java应用程序编程接口

java.lang包:Enum、包装类、Math、String、StringBuffer、System

枚举类enum:由一组固定的常量组成的类型

[Modifier] enum enumName{

    enumContantName1

}

public enum Gender{

    Male,Female

}

public class Student{

    public Gender sex; //枚举类型的变量

}

Student stu = new Student();

stu.sex=Gender.Male;

Obeject类:所有类的父类; 所有的Java类都直接或间接继承类java.lang.Object类

常被子类重写的方法:toString()返回对象字符串、hashCode()返回该对象哈希码值

equals()比较对象内存地址、getClass()返回运行时类Class对象

    // toString()源码
    public String toString() {
        if (isEmpty()) {
            return "[]";
        }
        StringBuilder buffer = new StringBuilder(size() * 16);
        buffer.append('[');
        Iterator<?> it = iterator();
        while (it.hasNext()) {
            Object next = it.next();
            if (next != this) {
                buffer.append(next);
            } else {
                buffer.append("(this Collection)");
            }
            if (it.hasNext()) {
                buffer.append(", ");
            }
        }
        buffer.append(']');
        return buffer.toString();
}
    // equals()源码
public boolean equals(Object anObject) {  
        if (this == anObject) {  
            return true;  
        }  
        if (anObject instanceof String) {  
            String anotherString = (String)anObject;  
            int n = value.length;  
            if (n == anotherString.value.length) {  
                char v1[] = value;  
                char v2[] = anotherString.value;  
                int i = 0;  
                while (n-- != 0) {  
                    if (v1[i] != v2[i])  
                        return false;  
                    i++;  
                }  
                return true;  
            }  
        }  
        return false;  
  }  

包装类:基本数据类型-->包装类

Object->Boolean-Number(Byte/Short/Integer/Long/Float/Double)-Character

    boolean -- Boolean   char -- Character

    byte -- Byte          short -- Short

    int -- Integer        long -- Long

    float -- Float        double -- Double

集合不允许存放基本数据类型数据,存放数字时,用包装类

包装类构造方法:

public Type(type value)    ex:Integer i=new Integer;

public Type(String value) ex:Integer i=new Integer(“123”);

// Number类型构造时,参数必须能转换为相应的数字,不然NumberFormatException

    Boolean类型构造时,除了true(大小写),其它false

包装类常用方法:

***Value() -- 包装类转换成基本数据类型

toString() -- 以字符串形式返回包装对象表示的基本数据类型

parse***() -- 把字符串转换为相应的基本数据类型(Character除外)

基本类型转换为包装类:Integer intValue = new Integer(16);

包装类转换为基本类型:Integer integerId = new Integer(25);

int intId = IntegerId.intValue();

装箱和拆箱:基本类型和包装类的自动转换(JDK1.5以后)

    Integer intObject=16; //装箱:基本类型转换为包装类的对象

    int intValue=intObject; //拆箱:包装类对象转换为基本类型的值

String(字符串常量):操作字符串,位于java.lang包中;

创建String对象两种方式:""直接赋值法、new关键字法

字符串连接: 使用”+”、String类concat()方法

内存分析:字符串常量池>栈内存(字符串名)>堆内存(字符串对象)

//字符串方法操作的变化都作用于字符串的副本本身无变化

//产生变化的方法:变大小写、连接、截取

获取方法

int length()             获取字符串长度

char charAt(int index)   获取特定位置的字符(交付月结)

int indexOf(String str)  获取特定字符的位置

int lastIndexOF(int ch)   获取最后一个字符位置

判断方法

boolean endsWith(String str)   是否以特定字符结束

boolean isEmpty()              是否为空(长度为0)

boolean contains(CharSequences) 是否包含指定字符序列

boolean equals(Object obj)      比较存储在两个字符串对象的内容是否一致

boolean equalsIgnoreCase(String str) 忽略大小写是否相等

equals()与==区别:一开始,equals()与==作用一致(比较两个字符串内存地址是否一致,是否为同一对象);后来,字符串对equals()方法进行了重写,equals()变成类比较两个字符串内容是否相等。

String s1="java";//s1,s2,s3都位于栈区

String s2="java";//s1,s2指向字符串池的同一个字符串”java”对象

String s3=new String("java");//创建两个”java”对象,但与串池重复,不用再放入串池中,且s3指向放入堆区的”java”对象

转换方法

  String(char[] value)     将字符数组转换为字符串

   String(char[] value,int offset,int count)

   String valueOf(char[] data)

   String valueOf(char[] data,int offset,int count)

   char[] toCharArray()     将字符串转换为字符数组

其他方法

String replace(char oldChar,char newChar) 替换

String[] split(String regex)             切割

String substring(int beginIndex)         截取字符串

String substring(int beginindex,int endindex)

String toUpperCase()     转大写

String toLowerCase()     转小写

String trim()            去除空格

StringBuffer:可变字符串缓冲区;对字符串频繁修改时,效率高于String

StringBuffer str=new StringBuffer(“content”);//String->StringBuffer

str.append();       //缓冲区的尾部追加字符串

str.insert();       //在指定的下标位置添加新的文本对象

str.toString(); //StringBuffer->String

str.reverse()        //把字符串反序输出

StringBuilder:与StringBuffer相似;单线程,线程不安全;效率更高

System(获取系统的属性)-Runtime(应用程序运行环境)

Date(日期类)-Calendar(日历类java.util.Calendar,封装年月日时分秒时区,)

String now=new SimpleDateForamte(yyyy-MM-dd HH:mm:ss).format(date); //格式转换

Math:封装常用数学运算方法和两个静态常量E(自然对数底数)和PI(圆周率)

    Math.abs()绝对值、Math.max()、Math.random()随机值

Random:java.util.Random类

    //用同一个种子值来初始化两个Random对象,每个对象调用相同方法,得到的随机数也是相同的

    Random rand=new Random(int seed);

    int num=rand.nextInt();

正则表达式(操作字符串的规则):匹配功能-切割功能-替换功能-获取(正则对象Pattern +匹配器Matcher)

str.matches(“正则表达式”)

预定义字符类:

.         任何字符(与行结束符可能匹配也可能不匹配)

\d        数字:[0-9]

\D        非数字: [^0-9]

\s        空白字符:[ \t\n\x0B\f\r]

\S        非空白字符:[^\s]

\w        单词字符:[a-zA-Z_0-9]

\W        非单词字符:[^\w]

^         行的开头

$         行的结尾

\b        单词边界

\B        非单词边界

\A        输入的开头

\G        上一个匹配的结尾

\Z        输入的结尾,仅用于最后的结束符(如果有的话)

\z        输入的结尾

Greedy 数量词:

X?         X,一次或一次也没有

X*         X,零次或多次

X+         X,一次或多次

X{n}      X,恰好n

X{n,}     X,至少n

X{n,m}     X,至少n次,但是不超过m

范围表示:

[abc]         ab c(简单类)

[^abc]         任何字符,除了 ab c(否定)

[a-zA-Z]      a z A Z,两头的字母包括在内(范围)

[a-d[m-p]]     a d m p[a-dm-p](并集)

[a-z&&[def]]  de f(交集)

[a-z&&[^bc]]  a z,除了 b c[ad-z](减去)

[a-z&&[^m-p]] a z,而非 m p[a-lq-z](减去)

输入/输出I/O

文件(记录或数据的集合)-路径(相对路径/绝对路径)

File:java.io.File包;文件的属性

File类的构造方法:

    File(String pathname)            指定文件路径

    File(String dir,String subpath)  dir目录路径,subpath文件名

创建:

createNewFile() 在指定位置创建一个空文件,成功返回true,如果存在不创建然后返回false

mkdir()     在指定位置创建目录,只会创建最后一级目录,如果上级目录不存在就抛异常

mkdirs()    在指定位置创建目录,会创建路径中所有不存在的目录

renameTo(File dest)  重命名文件或文件夹,也可以操作非空的文件夹

删除:delete()   删除文件或一个空文件夹,如果是文件夹且不为空,则不能删除

判断:

exists()        文件或文件夹是否存在

isFile()        是否是一个文件,如果不存在,则始终为false

isDirectory()   是否是一个目录,如果不存在,则始终为false

isHidden()      是否是一个隐藏的文件或是否是隐藏的目录。

isAbsolute()     测试此抽象路径名是否为绝对路径名

获取:

getName()       获取文件或文件夹的名称,不包含上级路径。

getPath()         返回绝对路径,可以是相对路径,但是目录要指定

getAbsolutePath()获取文件的绝对路径,与文件是否存在没关系

length()        获取文件的大小(字节数),如果文件/文件夹不存在则返回0L

getParent()     返回此抽象路径名父目录的路径名字符串;如果没有指定父目录,则返回null

lastModified()  获取最后一次被修改的时间

文件夹相关:

staic File[] listRoots()     列出所有的根目录(Window中就是所有系统的盘符)

list()                      返回目录下的文件或者目录名,包含隐藏文件

list(FilenameFilter filter)  返回指定当前目录中符合过滤条件的子文件或子目录

listFiles()                 返回目录下的文件或者目录对象,包含隐藏文件

listFiles(FilenameFilter filter) 返回指定当前目录中符合过滤条件的子文件或子目录

I/O:一组有序的数据序列;以先进先出方式发送信息的通道

输入/输出与数据源:源数据源--流--读-->程序

程序-->写--流--目标数据源

输入输出流是相对于计算机内存(程序): 文件-输入->内存-读 内存数据-写->输出-文件

Java:字节流(InputStream|OutputStream)-字符流(Reader|Writer)

    缓冲字符流 BufferedReader|BufferedWriter

序列流SequenceInputStream

按流向区分:输出流(OutputStream和Writer作为基类)

输入流(InputStream和Reader作为基类)

按处理数据单元分:

字节流(字节输入流InputStream基类和字节输出流OutputStream基类);8位字节流

字符流(字符输入流Reader基类和字符输出流Writer基类);16位Unicode字符流

InputStream:常用子类FileInputStream,用于从文件中读取数据

int read()/read(byte[] b,int start,int len)    -- 读取数据到字节数组b

void close()     -- 关闭输入流

OutputStream:常用子类FileOutputStream,用于向文件写数据

    void write()/write(byte[] b,int start,int len) --字节数组b输出到输出流

    void close()     -- 关闭输出流

Reader:常用子类BufferedReader,接受Reader对象作为参数,添加到字符缓冲区

    int read()/read(char[] c,int off,int len) --从输入流读取保存到字符数组c

    void close()    -- 关闭流

Writer: 常用子类BufferedWriter;数据缓冲到字符输出流

    write(String str,int off,int len) --将str字符串输出到指定输出流中

    void flush()     -- 刷新输出流

    void close()     -- 关闭输出流

读写文本文件

字节流:FileInputSteam和FileOutputStream

  1. 引入相关的类
  2. 构造文件输入流FileInputSteam对象:FileInputStream构造方法

构造文件输出流FielOutputSream对象: FileOutputStream构造方法

  1. 读取文本文件的数据  把数据写入文本文件
  2. 关闭文件流对象:fs.close()

字符流:FileReader和FileWriter

  1. 引入相关类:import.io.Reader/FileReader/IOException
  2. 创建FileReader对象:Reader fr=new FileReader(“D:\\Doc\\hello.txt”);

创建FileWriter对象:Writer fw=new FileWriter(“D:\\Doc\\hello.txt”);

  1. 读取文本文件的数据:fr.read();

写入数据:fw.write(“”);

  1. 关闭相关的流对象:fr.close();fw.close();

public class IODemo {

    public static void main(String[] args) throws IOException{

        /* */

//1 创建流对象

        FileInputStream fis = new FileInputStream("C:\\Doc\\hello.txt");

        int data;

        System.out.println("可读取的字节数:"+fis.available());

        System.out.println("文件内容为:");

        //2 循环读数据

        while((data=fis.read()) != -1){

            System.out.println(data+"");

        }

        //3 关闭流对象

        fis.close();

        try {

            String str = "java";

            byte[] words = str.getBytes();//字节数组

            /* */

//1 创建流对象,以追加方式进入文件

            FileOutputStream fos = new FileOutputStream("C:\\Doc\\hello.txt",true);

            //2 写入文件

            fos.write(words,0,words.length);

            System.out.println("hello文件已更新!");

            //3 关闭流对象

            fos.close();       

        } catch (IOException obj) {

            System.out.println("创建文件时出错!");

        }

    }

}

BufferedReaderBufferedWriter:带有缓冲区的字符流

BufferedReader--FileReader BufferedWriter--FileWriter

构造方法:BufferedReader(Reader) BufferedWriter(Writer)

方法:Read() write() flush()

序列流(合并流):SequenceInputStream

构造函数:SequenceInputStream(InputStream s1, InputStream s2)

序列化-反序列化:ObjectOutput-ObjectInput

实现类:ObjectOutputStream- ObjectInputStream

序列化Serializable:将对象的状态写入到特定的流中的过程

对象(内存)-->流(二进制的字节序列)

反序列化:从特定的流中获取数据重新构建对象的过程

流(二进制的字节序列)-->java对象(内存)

/* 使用序列化保存对象信息 */

//1.实现Serializable接口

/*public class Student implements Serializable{

}*/

ObjectOutputStream oos = null ;

try {

//2.创建对象输出流:ObjectOutputStream

oos = new ObjectOutputStream(new FileOutputStream("C:\\myDoc\\stu.txt"));

//3.调用writeObject()方法将对象写入文件

Student stu = new Student(1,"java",10);

oos.writeObject(stu);

} catch (Exception e) {

  e.printStackTrace();

} finally{

  //4.关闭对象输出流

  if(oos != null){

      oos.close();

  }

}

使用反序列化获取对象信息:

//1.实现Serializable接口

ObjectInputStream ois = null;

try {

    //2.创建对象输入流: ObjectInputStream

    ois = new ObjectInputStream(new FileInputStream("C:\\myDoc\\stu.txt"));

    //3.调用readObject()方法读取对象 (反序列化,强转类型)

    Student stu = (Student) ois.readObject();

} catch (Exception e) {

    e.printStackTrace();

}finally{

    //4.关闭对象输入流

    if(ois != null){

        ois.close();

    }

}

反射

反射:在编译时不确定哪个类被加载,而在程序运行时才加载、探知、使用;动态获取信息以及动态调用对象方法的功能(.class文件->Class对象->类及属性方法)

Java反射(Java.lang.reflect):类(Class)-构造方法(Constructor)-属性(Field)-普通方法(Method)

  1. Class类:反射的核心类,可以获取类的属性、方法等内容信息
  2. Constructor类:表示类的构造方法
  3. Field类:表示类的属性,可以获取和设置类中属性的值
  4. Method类:表示类的方法,可以用来获取类中方法的信息或者执行方法

获取Class对象三种方式:Class.forName()、类名.class、对象.getClass()

    forName方法用于加载某个类的字节码到内存中,并使用class对象进行封装

反射操作:

通过Class类获取类型信息:

getName()       类的名称(全名,全限定名)

getSimpleName() 类的的简单名称(不带包名)

getModifiers(); 类的的修饰符

创建对象: newInstance()   无参数构造创建对象

  获取指定参数的构造器对象,并可以使用Constructor对象创建一个实例

      Constructor<T> getConstructor(Class<?>... parameterTypes)

通过Class类获取类型中方法信息:

  Method[] getMethods()        获取公共方法包括继承的父类的方法,返回一个Method数组

  getMethod("setName", String.class);   获取指定参数的公共方法

  Method[] getDeclaredMethods()         获得所有的方法,包括私有

  Method getDeclaredMethod(String name, Class<?>... parameterTypes) 获得指定参数的方法,包括私有

通过Class类获取类型中的字段的信息:

Field[] getFields()  获取公共字段

    Field getField(String name)  获取指定参数的公共字段

    Field[] getDeclaredFields()  获取所有的字段

    Field getDeclaredField(String name) 获取指定参数的字段,包括私有

/* class对象创建的三种方式 */

    //形式一 .class

    Class clz1=Person.class;

    //形式二 对象.getClass()

    Person p=new Person();

    Class clz2=p.getClass();

    //形式三 Class.forName()

    Class clz2=Class.forName("cn.hfxt.reflect.Person");

// 动态创建其对象:根据class对象,动态调用默认构造创建真实Person对象.

    Object obj = c1.newInstance();

    //获取类中指定参数的构造方法对象.并动态调用此构造进行真实Person对象创建.

    Constructor con= c3.getConstructor(String.class);

    Object obj = con.newInstance("张三");

    Constructor[] cons = c3.getConstructors();//获取其所有构造:

    /*权限类: AccessibleObject : Constructor / Field / Method;

        常见方法: isAccessible()

                 setAccessible(AccessibleObject[] array, boolean flag)*/

//动态操作对象的属性:根据反射得到class对象. 进行属性操作

    //1.先得到一个class

    Class c1 = Class.forName("cn.bdqn.clas.Person");

    //2.class对象中的指定属性获取

    //Field[] fs = c1.getFields();

    Field f1 = c1.getField("name");

    //3.创建真实对象,来进行属性操作.

    Object p = c1.newInstance();

    //给指定真实对象中的属性赋值

    f1.set(p, "zhangsan");

    //从真实对象中获取指定属性的值

    Object nameValue = f1.get(p);

    System.out.println( nameValue );

//动态操作对象的方法:根据反射得到class对象. 进行方法操作

    //1.先得到Class对象.

    Class c1 = Class.forName("cn.bdqn.clas.Person");

    /*//形式一: 动态操作无参方法.

     //2.Class中的指定方法获取.

    Method m1 = c1.getMethod("show",null);

    Object o1 = c1.newInstance();

    //3.动态执行此方法.

    m1.invoke(o1, null);*/

    //形式二: 动态操作带参方法.

    Method  m1 = c1.getMethod("show2", String.class,int.class);

    Object o1  = c1.newInstance();

    //如果静态,需要真实对象o1. null就行.

    m1.invoke(o1, "lisi",20);

注解和多线程

元数据:描述数据的数据

注解:Java代码的特殊标记;修饰程序元素(包、类、构造方法、方法、成员变量、参数、局部变量的声明)的形式化方法; 不影响程序代码的执行。

注解的类型是一个接口:程序可以通过反射来获取程序元素的注解对象;单独置于一行

不带参数的注解:@Annotation

带参数的注解:@Annotation({“参数1”,”参数2”,…”参数n”})

    @MyTag(name=”Jack”,age=20)

内建注解(基本注解):定义于java.lang包中

    限定重写父类方法:@Override

    标记已过时:@Deprecated

    抑制编译器警告:@SuppressWarnings(value=”unchecked/path/serial/all”)

元注解:@Retention @Target @Documented @Inherited

自定义注解:@interface

public @interface AnnotationTest{

      //成员变量

      String name() default “Jack”;

      int age() default 20;

}

进程与线程

进程:应用程序的执行实例;有独立的内存空间和系统资源

线程:CPU调度和分派的基本单位;进程中执行运算的最小单位,处理机分配给线程,真正在CPU上运行的是线程

Java程序中:每个独立的小程序都是一个进程,而程序中main方法就是唯一的一个线程,

称为主线程;Java 虚拟机允许应用程序并发地运行多个执行线程

使用线程的步骤:定义线程>创建线程>启动线程>终止线程

1.创建线程的两种方式:

继承java.lang.Thread类:extends Thread

实现java.lang.Runnable接口:implements Runnable

2.重写run()方法

3.启动线程:start()而非run()

class PrimeThread extends Thread {

long minPrime;

PrimeThread(long minPrime) {

this.minPrime = minPrime;

}

public void run() {

...

}

}

PrimeThread p = new PrimeThread(143);

p.start();

线程的生命周期:新生状态>可运行状态-阻塞状态>死亡状态

优先级:反映线程的重要或紧急程度(多个线程处于可运行状态)

    线程的优先级用1~10(high)表示>更改优先级setPriority(int grade)

线程调度:join() -- 将指定的线程加入当前线程

        sleep() -- 将当前线程阻塞指定的毫秒数

线程同步:同步方法(synchronized)、同步代码块(synchronized)

死锁:多个线程都处于等待状态而无法唤醒,就构成了死锁,此时处于等待状态的多个线程占用系统资源,但无法运行,因此不会释放自身的资源

网络编程技术

端口port(端口号)-IP地址(网络地址+主机地址)-DNS域名解析(域名系统)

网络服务器:客户机Client/服务器Server(C/S模式)-浏览器Browser/Server(B/S模式)

套接字Socket(两台机器间通信的端点;java.net包):

客户端Socket、服务器ServerSocket

流式套接字:基于TCP协议的Socket网络编程

TCP:面向连接;传输可靠;速度慢

数据包式套接字:基于UDP协议的Socket网络编程

UDP:面向非连接;传输不可靠;速度快

基于TCP协议的Socket编程

Socket网络编程的步骤:(网络编程模型C/S)

服务器端:捕获一个Socket对象,进行解析

//1.创建服务器Socket -- 建立连接

    ServerSocket serverSocket=new ServerSocket(5000);

    //2.使用accept()方法等待客户的通信

    Socket socket=serverSocket.accept();

    //3.获得输入流,获得相应的用户请求 -- (输出流--装载数据 输入流--提取数据)

    InputStream is=socket.getInputStream();

    BufferedReader br=new BufferedReader(new InputStreamReader(is));

    String info;

//数据流中读取信息

    while((info=br.readLine())!=null){

        System.out.println("客户端说:"+info);

    }

//4.给客户端一个响应 -- 关闭所有的数据流和Socket

    String reply="欢迎登陆!";

    byte[] replys=reply.getBytes();

    OutputStream os=socket.getOutputStream();

    os.write(replys);

    //5.释放相应资源

    os.close();

    br.close();

    is.close();

    socket.close();

    serverSocket.close();

客户端:发送+接收

//1.创建客户端Socket

    Socket socket=new Socket("localhost",5000);

    //2.通过输出流发送请求

    OutputStream os=socket.getOutputStream();

    String info="用户名:TOM;密码:123456";

    byte[] infos=info.getBytes();

    os.write(infos);

    //3.通过输入流接收到服务器给客户端的响应

    socket.shutdownOutput(); //关闭输出流

    InputStream is=socket.getInputStream();

    BufferedReader br=new BufferedReader(new InputStreamReader(is));

    String reply;

    while((reply=br.readLine())!=null){

        System.out.println("服务器的响应:"+reply);

    }

    //4.释放资源

    br.close();

    is.close();

    os.close();

    socket.close();

基于UDP协议的Socket编程:DatagramPacket

发送方:

//1.创建仓库,并负责装载数据

    String info="使用Java高级实用技术";

    byte[] buffer=info.getBytes("GBK");

    InetAddress ip=InetAddress.getByName("127.0.0.1");

    DatagramPacket packet=new DatagramPacket(buffer,

    buffer.length,ip,9999);

    //2.发送数据包

    DatagramSocket socket=new DatagramSocket();

    socket.send(packet);

    //3.关闭

    socket.close();

接收方:

    //1.创建空仓库,并负责装载数据

    byte[] buffer=new byte[1024];

    DatagramPacket packet=new DatagramPacket(buffer,1024);

    //2.接收数据包

    DatagramSocket socket=new DatagramSocket(9999);

    socket.receive(packet);

    System.out.println(new String(packet.getData(),0,packet.getLength()));

    //3.关闭

    socket.close();

软件测试

白盒测试(结构测试或逻辑驱动测试)-黑盒测试(功能测试)-单元测试(方法测试)

Junit测试框架junit3(extends TestCase)-junit4(注解的形式)

XML技术

XML(Extensiable Markup Language):可扩展标记语言

XML文档基本结构

<元素名 属性名="属性值">元素内容</元素名> <!-- 属性值不能直接包含<& -->

空元素:<name> </name> <name></name> <name/>

<?xml version=”1.0” encoding=”UTF-8”?>  //声明

<!-- DTD验证xml -->

<!DOCTYPE books[  

    <!ELEMENT books (book*)>

    <!ELEMENT book (author+,title+,description?)>

    <!ATTLIST book ID CDATA #REQUIRED>

    <!ELEMENT author (#PCDATA)>

<!ELEMENT title (#PCDATA)>

<!ELEMENT description (#PCDATA)>

]>

<books> //根元素  文档元素描述信息文档结构

    <!—图书信息--> //注释

    <book id=”bk101”> //元素-属性

        <author>bdqn</author>

        <title>java</title>

        <description>编程</description>

</book>

</books>

XML转义符(预定义实体):<(&lt;)、>(&gt;)、“(&quot;)、‘(&apos;)、&(&amp;)

CDATA节:(元素中出现很多特殊字符)

    <description>

    <![CDATA[了解XML元素<title></title>的使用]]>

</description>

XML命名空间

元素或者属性命名空间格式:xmlns:***=”URL”

默认命名空间:xmlns=”URL”

XML解析器:非验证解析器(格式是否良好) 验证解析器(DTD检查文档的有效性

DTD:文档类型定义,Document Type Definition;元素/元素之间关系/属性的定义规则

DTD文档的声明及引用:

    内部DTD文档(Stu.xml):<!DOCTYPE 根元素 [定义内容]>

    外部DTD文档(Stu.xml Stu.dtd):<!DOCTYPE 根元素 SYSTEM “DTD文件路径”>

内外部DTD文档结合:<!DOCTYPE 根元素 SYSTEM “DTD文件路径” [定义内容]>

DTD元素:<!ELEMENT NAME CONTENT>

          关键字 元素名称 元素类型

元素类型:

EMPTY--空元素,该元素不能包含子元素和文本,但可以有属性 <!ELEMENT 人 EMPTY>

#PCDATA--可以包含任何字符数据,但是不能在其中包含任何子元素纯元素类型

<!ELEMENT 人 (#PCDATA)>

纯元素类型--只包含子元素,并子元素外没有文本

ANY--该元素可以包含任何在DTD中定义的元素内容

符号

用途

示例

()

给元素分组

(a|b|c),(a|d),a

|

在列出的对象中选择一个

(A|B)

,

对象必须按指定的顺序出现

(a,b,c)

*

该对象允许出现零次到任意多次(0到多次)

(a*)

?

该对象可以出现,但只能出现一次(0到1次)

(a?)

+

该对象最少出现一次,可以出现多次(1或多次)

(a+)

DTD属性

<!ATTLIST 元素名称

属性名称 属性类型 属性特点

>

属性类型:CDATA、ID、IDREF/IDREFS、Enumerated

属性特点:#REQUIRED、#IMPLIED、#FIXED value、Default value

XML解析DOM-SAX-DOM4J

DOM:基于XML文档树结构的解析;适用于多次访问的XML文档

文档对象模型(Document Object Model):把XML文档映射成一个倒挂的树(元素节点 属性节点 文本节点)

DOM解析的常用对象:Document文档,NodeList节点列表,Node单个节点,Element元素

DOM解析XML文件步骤:

  1. 创建解析器工厂对象,即DocumentBuilderFactory对象
  2. 解析器工厂对象创建解析器对象,即DocumentBuilder对象
  3. 由解析器对象对指定的XML文件进行解析,构建相应的DOM树,创建Document对象
  4. 以Document对象为起点对DOM树的节点进行增加、删除、修改、查询等操作

SAX:基于事件的解析;适用于大数据量的XML文档

DOM4J:非常优秀的Java XML API;开源

Document:文档 Element:元素 Attribute:属性 Text:文本节点

使用DON4J解析XML的步骤:

  1. 导入don4j的jar包,导入相应的类
  2. 指定要解析的XNL文件
  3. 把XML文件转换成Document对象
  4. 获取节点属性或文本值

解析xml文档:

  1. 通过SAXReader解析器读取File/InputStream获得Document对象
  2. Elemment root=Document对象.getRootElement;//获得根元素
  3. Element的常用方法:

element(“标签名”);//获得一个子标签

elements(“标签名”);//获得子标签List

elementIterater(“标签名”);//获得子标签Iterater

---------------------------------------------

getText();获得当前标签的文本内容

---------------------------------------------

attribute(“属性名”);//获得指定名称的Attribute对象

attributeValue(“属性名”);//获得指定名称属性的内容

猜你喜欢

转载自blog.csdn.net/ftmy_c/article/details/81209890
今日推荐