【Android -- 基础】Java 知识点(入门篇)

前言

本文主要是复习一下 Java 基础中的知识点总结。java 的知识点非常的多,它更像是一个成熟稳重的中年大叔。有些我们自以为理解了的知识点,其实只是停留在了他的表面之上,并没有深入了解到其实现原理。

纸上得来终觉浅,绝知此事要躬行。

概述

1. Java 之父
Java 是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 面向对象程序设计语言和 Java 平台的总称。由 James Gosling 和同事们共同研发,并在 1995 年正式推出。

2. Java 三大体系

  • javaSE,标准版,各应用平台的基础,桌面开发和低端商务应用的解决方案。
  • javaEE,企业版,以企业为环境而开发应用程序的解决方案。
  • javaME,微型版,致力于消费产品和嵌入式设备的最佳方案。

3. Java 的特性

  • 一种面向对象的编程语言。
  • 一种与平台无关的语言(根据JVM实现的)。
  • 一种健壮性语言。
  • 具有较高的安全性。

4. GC、JDK 和 JRE

  • GC:垃圾回收器
    在 java 运行过程中自动启动,程序员无法干预。
  • JDK:java开发工具包
    先编译(编译器javec),后运行(解释器java)
  • JRE:java运行环境
    加载代码(加载器),校验代码(校验器),执行代码(解释器)

5. Java 虚拟机
java 虚拟机实际上只是一层接口,一层 Java 程序和操作系统通讯的接口。java 文件编译生成 class 文件,而 java 虚拟机就是这些 class 文件能够在上面运行的一个平台,你把 class 文件看成一个软件,java虚拟机就是这个软件可以运行的操作系统。

环境变量配置(Windows 10)

1. JDK 下载

官网下载地址:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

同意协议后,下载相应 JDK 版本。

2. 在桌面右键此电脑–>选属性–>高级系统设置–>环境变量设置–>系统变量中点新建
变量名:JAVA_HOME
变量值:C:\Program Files\Java\jdk1.8.0_202(你JDK的安装路径)

3. 再次点击新建输入
变量名:CLASSPATH
变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar(需要注意前面有个点)

4. 找到 Path 点编辑,进去之后点新建

在后面添加 %JAVA_HOME%\bin %JAVA_HOME%\jre\bin(注意不需要添加;号,直接另起一行即点击新建添加即可)最后点击确定!

5. 验证
按 win+R 键 输入 cmd 回车 进入 dos,分别输入 java javac 查看安装是否完成,出现如图即安装成功!

面向对象的三大特性

1、封装

作用:提高代码的安全性
1、将属性私有化,并提供对外界的接口( get / set 方法)。
2、用 private 修饰的属性和方法,只能在本类中使用。

2、继承

作用:提高代码的复用性,减少重复代码

    1、子类可以继承父类非私有的属性和方法,不能继承构造方法和私有的属性和方法。

    2、可以综合子类的共同特征来去提炼父亲的类。

    3、子类在继承父类的各种属性和方法时,也可以有自己的属性和方法。

    4、一个子类只能有一个父类,java只能单继承,不能多继承,因为多个类中的方法名相同,方法体不同,不知使用哪个。

    5、一个类继承最顶端叫做基类或者超类,所有的超类叫做object 。

    6、在继承关系中,如果父类没有无参数的构造方法,如何解决?

           1>子类中添加一个和父类构造方法参数列表相同的构造方法,通过super参数传递给父类的构造方法

           2>如果父类允许修改的时候,可以在父类中创建一个无参的构造方法

    7、在继承关系中,代码块的执行顺序:父静>子静>父构造代码块>父构造方法>子构造代码块>子构造方法

3、多态

    1、分类

        编译时多态:在编译过程中察觉的多态,重载,向上转型。

        运行时多态:在运行过程中察觉的多态,向下转型。

    2、向上转型、向下转型是在继承关系中,向下转型必须在向上转型的基之上。

    3、在继承关系中,父类的对象可以指向子类的实例,父类引用实体方法的时候,是调用子类重写以后的方法。

    4、向上转型

        父类的引用指向子类的实体

        父类类名 对象名=new 子类类();

        优点:减少重复代码,提高代码的复用性

        缺点:父类的引用无法调用子类特有的属性和方法

        解决方案:向下转型

    5、向下转型:

        子类对象的父类引用赋给子类

        子类类名 对象名=(子类类名)父类对象;

    6、 instanceof 判断左边的对象是否属于右边的类  对象名 instanceof 类名(子类类名)

    7、匿名对象

        new 类名()  只有堆空间,没有栈空间,只能属于一次,为了节省代码。

4、程序设计 6 大原则

1、单一职责原则
2、里氏替换原则
3、依赖倒置原则
4、接口隔离原则
5、迪米特法则
6、开闭原则

编程基础

1. 基本数据类型

1、基本数据类型:

    数值型:byte     1字节   8位   -128~127

        short    2字节   16位  -32768~32767

        int      4字节   32位  -2^31~2^31-1

        long     8字节   64位  2^63~2^63-1

    浮点类型:

        float    4字节   32位  

        double   8字节   64位

    字符型:char     2字节   16位   0~65535

    布尔型:boolean  true    false

2、引用类型:

    字符串 String、 类 class 、枚举 enum、接口interface

2. 变量

1、数据类型划分:

    基本类型变量:数据的值

    引用类型变量:数据的地址

2、声明的位置划分:

    局部变量

    全局变量

        区别:

        1、默认值

            局部没有默认值,使用前必须初始化。

            全局有默认值,默认为0,不必须初始化。

        2、声明位置

            局部在方法内。

            全局在方法外类内。

        3、作用位置

            局部只能在自己声明的方法里。

            全局在整个类中

3. 运算符

算术运算符:+ 、 - 、 * 、 / 、 % 、 ++ 、 --

赋值运算符:= 、 += 、 -= 、 *= 、 /= 、 %=

关系运算符:> 、 < 、 >= 、 <= 、 == 、 !=

逻辑运算符:! 、 & (只要有一个false  最终结果就是false) 、

         | (但凡有一个true   最终结果就是true) 、

         ^ (如果两边一样     最终结果为false   如果两边不同   最终结果为true)、

         &&(如果第一个是false 那第二个不执行  最终结果是false)、

         ||(如果第一个表达式的结果是true 那第二个表达式 就不去计算了 ,最终结果是true)

位运算符: ~ 、 >> 、 << 、 >>>

字符串连接运算符:+

三目运算符:X ? Y : Z

            X为boolean类型表达式,先计算x的值,若为true,整个三目运算的结果为表达式Y的值,否则整个运算结果为表达式Z的值。

4. if 语句

1、if(){}

2、if(){}else{}

3、if(){}else if(){}

4、if(){if(){}else()}    

5、if()执行语句 esle   执行语句 注意:执行语句只有一条语句的时候.可以将if esle 的大括号省略

注意:()内是boolean类型表达式,{}是语句块

    比较字符串用equals,比较内容。比较数值用==,比较地址。

    基本数据类型:变量名、变量值在栈中。

    引用数据类型:变量名在栈中,变量值在常量池中。

5. switch 语句

switch(表达式expr){

    case const1:

        statement1;

        break;

    … …

    case constN:

        statementN;

        break;

    [default:

        statement_dafault;

        break;]

}

注意:1、表达式必须是int、byte、char、short、enmu、String类型

      2、constN必须是常量或者finall变量,不能是范围

      3、所有的case语句的值不能相同,否则编译会报错

      4、default可要可不要

      5、break用来执行完一个分支后使程序跳出switch语句块,否则会一直会执行下去。

6. for 循环

for ([循环变量初始值设定]; [循环条件判断]; [改变循环变量的值]){

        循环体

}

注意:1、表达式2一般不可以省略,否则死循环

      2、表达式3可以省略,但是在循环体中必须有语句修改变量,以使表达式2在某一时刻为false结束循环。

      3、若同时省略表达式1,表表达式3,则相当于while(表达式2)语句

      4、三个表达式均省略 即for(;;)语句,此时相当于while(true)语句

      5、表达式1、表达式3可以是逗号表达式,以使循环变量值在修改时可以对其它变量赋值

------------------------------------------------------------------------------------------------------------
break 和 continue
1、break 跳出某个循环
2、continue 跳过某个循环

7. 方法

1、为什么使用方法?

    减少重复代码,提供代码复用性

    使用方法将功能提炼出来

    写在类内

2、声明格式

    [修饰符] 返回值类型 方法名([形式参数列表]){

              程序代码;

              [return 返回值;]

            }

   注意:1、方法是给外界提供内容的位置,形式参数是外界提供的

     2、方法调用的时候写的是实际参数

     3、实际参数的类型、顺序和形参要对应上

     4、支持自动转换类型,不支持强制类型转换

8. 抽象类和接口的区别

1、关键字:抽象类 abstract      接口interface

2、抽象类继承 extends         接口实现 implements

3、子类继承抽象类和          实现类实现接口的格式不同

4、接口中只有全局变量和抽象方法        抽象类中有各种属性和方法

5、抽象类只能单继承              接口可以多实现

6、抽象类的子类只能继承一个父类    实现类可以实现多个接口,并且还可以继承父类

7、抽象类的作用:提高代码的复用性   接口的作用:1、规范代码2、提高代码的拓展新

9. 重写和重载的区别

1、重写是在继承关系中             重载是在同一个类中

2、重写是方法名、参数列表和父类相同      重载,方法名相同,参数列表不相同(个数、类型、顺序)

3、重写返回值类型和父类相同          重载和返回值无关

4、重写访问权限修饰符不能比父类更加严格 重载没有要求

10. final finally finalize 区别

final 最终的,可修饰类,方法,属性

      类:不能被继承

      方法:不能被重写,可以被继承

      属性:全局变量:声明是必须初始化。局部变量:声明的时候可以不初始化。但都只能赋值一次

finally 跟try/catch后面,无论是否发生异常都会被执行。关闭数据库,关闭数据流。

finalize 由系统调用,垃圾回收器回收之前做一些清理的工作。

11. 设计模式

1、单例模式

    分类:懒汉式、饿汉式

    1、构造方法私有化

    2、在本类中创建本类对象

    3、保证对象的唯一性final

    4、给外界提供得到对象的方法 static

    5、在多线程中,饿汉式安全,懒汉式不安全

2、简单工厂模式

    批量创建对象

    1 创建工厂类 : 创建对象的方法

    2 果汁类 是所有种类果汁的父类

    3 在工厂类的方法中返回果汁类

    4 根据测试类中传递的字符串判断到底返回哪种果汁

    5 测试类通过工厂类返回果汁对象

3、建造者模式 

    内部类使用场景

    目的:静态内部类创建外部类对象

    1、 创建外部类,在其中创建一个静态内部类

    2、静态内部类中写属性,构造方法和set get方法

    3、静态内部类中写一个方法,必须返回外部类对象

    4、 给外部类创建对象,传递参数。

4、装饰者模式

    1、在处理流中使用

    2、子类重写父类的方法,提高父类方法的功能及效率

    3、为了尽可能减少重复代码,在重写的方法中用父类的对象调用父类原来的方法

    4、得到父类对象可以通过将父类对象作为子类属性,通过子类构造方法传递父类对象

数组及常用算法

1、声明:

  int a[];  int []b;

2、初始化:

    动态初始化:1、a=new int[2]; int[0]=1;...

    动态初始化:2、b=new b[]{3,4};

    静态初始化:int [] c={5,6};

3、数组常用的方法:

    排序:Array.sort();

    查找:Array.binarySearch();

    打印:Array.toString();

    复制:Array.copyof();

4、常用操作

    1、冒泡排序

    for(int i=0;i<a.length-1;i++){//控制外循环的次数

        for(int j=0;j<a.length-1-i;j++){//控制内循环次数,比外循环少一次,与下一个比较

            if(a[j]>a[j+1]){

                int temp=a[j];

                a[j]=a[j+1];

                a[j+1]=temp;

            }

        }

    }

    2、选择排序

    for (int i = 0; i < a.length-1; i++) {

        int k=i;

        for (int j = i; j < a.length-1; j++) {

            if (a[k]>a[j+1]) {

                k=j+1;

            }

        }

        if(i!=k){

            int temp=a[i];

            a[i]=a[k];

            a[k]=temp;

        }

    }

    3、顺序查找

    public static int find(int []b,int a){

    for (int i = 0; i < b.length; i++) {

        if (a==b[i]) {

            return i;

        }

    }

    return -1;

    }

    4、二分查找

    public static int find(int b[],int a){

    int max=b.length-1;

    int min=0;

    for (int i = 0; i < b.length; i++) {

        int midle=(max+min)/2;

        if(a==b[midle]){

            return midle;

        }else if(a>b[midle]){

           min=midle+1;

        }else if(a<b[midle]){

            max=midle-1;

        }

    }
     return -1;
  }

Java 常用类

1. String 类

==                  比较地址

.equals()               比较内容

.equalsIgnoreCase()         忽略大小写比较是否相同

.charAt();              字符串截取出指定的下标开始

.compareTo()                比较大小

.compareToIgnore()          忽略大小比较

.concat()               将参数字符串连接到指定字符串后面

.contains()             是否包含参数字符串

.startsWith()               以指定前缀开头

.endsWith()             以指定后缀结尾

.indexOf("/")               第一次出现

.indexOf("/", 3)            指定位置开始索引

.lastIndexOf("/")           最后一次出现

.substring(string11.lastIndexOf("/")+1);截取指定位置

.substring(string11.lastIndexOf("/")+1, string11.lastIndexOf("."));//截取字符串,指定开始位置和结束位置

.replace('a', 'b')          替换指定字符串,替换所有的

.toUpperCase()              全部转为大写

.toLowerCase()              全部转成小写

.trim()                 去掉字符串前后的空格,中间的去不掉

2. StringBuffer 类

.append("abckjc");          追加

.insert(2, "mmm");          插入

.delete(2, 4);              删除,参数1是起始下标,参数2是结束下标,左闭右开

.reverse();             逆顺反转



    String         长度不可变

  StringBuffer   长度可变   线程安全        速度慢

  StringBuilder  长度可变   线程不安全   速度快

3. 正则表达式

字符类

[abc]       a、b、c其中任意一个

[^abc]      除了a、b、c中的任意一个

[a-zA-Z]     a-z或A-Z范围中的任意一个

[a-zA-Z0-9]  a-z A-Z 0-9 其中任意一个

[……]         可以自己定义范围

预定字符类

\d   数字0-9

\D   非数字0-9

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

\S   非空白字符:\s

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

\W   非单词字符\w

数量词

?     一次或者一次也没有

*      0次到多次

+      一次或者多次

{n}    恰好n次

{n,}   至少n次

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

 .matches();    匹配是否适合

 .spil();   拆分

4. 时间相关类

1、Date类

    .getTime();计算毫秒

2、SimpleDateFormat类  格式化时间

    .format();返回的是String字符串

3、Calendar接口  日历字段之间的转换提供了一些方法

    .get(Calendar.YEAR);

    .get(Calendar.MONTH);// 默认是当前月份减一    从0开始的  

    .get(Calendar.DAY_OF_MONTH);

    .get(Calendar.DAY_OF_WEEK);

        Calendar calendar = Calendar.getInstance();

    Date date = calendar.getTime();

4、Runtime运行时时间

    .freeMemory(); 当前的系统剩余空间

5、System.exit(0);退出程序,参数是0 是正常退出

   System.gc();调用垃圾回收器 ,不一定能够起来 ,只是起到一个促进的作用

5. Collection 类

   1、添加元素

    add(Objectobj); //add方法的参数类型是Object。以便于接收任意类型对象。

   2、删除元素

    remove(Objectobj);

    removeAll(另一集合);//调用者只保留另一集合中没有的元素。

    clear();//清空集合

   3、判断元素

    contains(Objectobj);//判断是否存在obj这个元素

    isEmpty();//是否为空

   null  没有初始化  只有栈空间没有堆空间

       empty 已经初始化了对象   这个容器中没有数据 

   4、获取个数,集合长度

    size();

   5、取交集

    retainAll(另一集合);//调用者只保留两集合的共性元素。 

6. List 类

List:元素是有序的,元素可以重复。因为该集合体系有索引。

        |--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。

        |--LinkedList:底层使用的是链表数据结构。特点:增删速度很快,查询稍慢。

        |--Vector:底层是数组数据结构。线程同步。被ArrayList替代了。

ArrayList:

    增:add();addAll(0,list2);

    获取:get(1);

    修改:set();

    截取:subList(0, 2);左闭右开

LinkedList:

    增:addFirst(); addLast();      jdk1.6后  offFirst(); offLast();

    获取:getFirst(); getLast();              peekFirst(); peekLast();

    删除:removeFirst(); removeLast();        pollFirst(); pollLast();

    压栈:push();

    弹栈:pop();

    逆序输出:linkedList.descendingIterator()

7. Set 类

Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复。     

       |--HashSet:底层数据结构是哈希表。线程不同步。 保证元素唯一性的原理:判断元素的hashCode值是否相同。如果相同,还会继续判断元素的equals方法,是否为true|--TreeSet:可以对Set集合中的元素进行排序。默认按照字母的自然排序。底层数据结构是二叉树。保证元素唯一性的依据:compareTo方法return 0Set集合的功能和Collection是一致的

1HashSet: 哈希表

    1、可以通过元素的两个方法,hashCode和equals来完成保证元素唯一性。如果元素的HashCode值相同,才会判断equals是否为true。

    如果元素的hashCode值不同,不会调用equals。

    2、hashcode是内存地址通过一定运算的到的int类型的数值。返回值是int类型的数据,各个属性的hash值。 相加

    3、hashcode值相同,也不一定是同一个对象 

    4、调用hashcode方法可以帮助去过滤调用完全不可能相同的 对象,提高执行效率

    5、equals最终确定两个对象是否相同的

    @Override

    public int hashCode() {

        // TODO Auto-generated method stub

        int code=name==null?0:name.hashCode();

        return code;

    }

    @Override

    public boolean equals(Object obj) {

        // TODO Auto-generated method stub

        if(obj==this){

            return true;

        }

        if (obj==null) {

            return false;

        }

        if (obj instanceof Person) {

            Person person=(Person)obj;

            if (this.name.equals(person.name)) {

                return true;

            }

                

    }

    return false;

}

8. Map 类

1)该集合存储键值对,一对一对往里存

      2)要保证键的唯一性

 Map

        |--Hashtable:底层是哈希表数据结构,不可以存入nullnull值。该集合是线程同步的。JDK1.0,效率低。

        |--HashMap:底层是哈希表数据结构。允许使用nullnull值,该集合是不同步的。JDK1.2,效率高。

        |--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给Map集合中的键进行排序。

    初始容量16,加载因子0.75

        MapSet很像。其实Set底层就是使用了Map集合。

    1、添加

        Vput(K key,V value);//添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有键对应值,并put方法会返回被覆盖的值。

        voidputAll(Map <? extends K,? extends V> m);//添加一个集合

    2、删除

        clear();//清空

        Vremove(Object key);//删除指定键值对

    3、判断

        containsKey(Objectkey);//判断键是否存在

        containsValue(Objectvalue)//判断值是否存在

        isEmpty();//判断是否为空

    4、获取

         Vget(Object key);//通过键获取对应的值

         size();//获取集合的长度

1HashMap

    HashSet底层封装HashMap,所以HashSet中的规律都是用于HashMap的键。值允许重复,允许多个null,键只允许一个null

    如果自定义类作为键,需要重写hashcode的和equals方法,保证事物唯一性。如果作为值,则不重写

        @Override

    public int hashCode() {

        // TODO Auto-generated method stub

        int code=name==null?0:name.hashCode();

        int code2=age;

        int code3=sex.hashCode();

        return code+code2+code3;

    }

    @Override

    public boolean equals(Object obj) {

        // TODO Auto-generated method stub

        if (this==obj) {

            return true;        

        }

        if (obj==null) {

            return false;

        }

        if (obj instanceof Person) {

            Person person=(Person) obj;

            if (this.name.equals(person.name)) {

                if(this.age==person.age){

                    if (this.sex.equals(person.sex)) {

                        return true;

                    }

                }   

            }

        }

        return false;

    }

2TreeMap

    1、自然排序

        public int compareTo(Person o) {

        // TODO Auto-generated method stub

        if (this.age<o.age) {

            return 1;

        }else if (this.age>o.age) {

            return -1;

        }else {

            CollationKey collationKey=Collator.getInstance().getCollationKey(this.name);

            CollationKey collationKey2=Collator.getInstance().getCollationKey(o.name);

            return collationKey.compareTo(collationKey2);

        }

    }

    2、定制排序

    单独写一个类

        public class GirlCom implements Comparator<Girl> {

        @Override

        public int compare(Girl o1, Girl o2) {

        // TODO Auto-generated method stub

        if(o1.age>o2.age){

            return 1;

        }else if(o1.age<o2.age){

            return -1;

        }else {

            if(o1.weight>o2.weight){

                return 1;

            }else if(o1.weight<o2.weight){

                return -1;

            }else {

                CollationKey collationKey=Collator.getInstance().getCollationKey(o1.name);

                CollationKey collationKey2=Collator.getInstance().getCollationKey(o2.name);

                return collationKey.compareTo(collationKey2);   

                    }

                }

            }

        }


    调用格式:TreeMap< Girl,String > treeMap=new TreeMap< Girl,String>(new GirlCom());   

9. File 类

创建:File file = new File(路径字符串);

    .exists();文件是否存在

    .delete();删除文件

    .getPath();路径

    .isFile());是文件吗

    .isDirectory();是目录吗

    .getName();名称

    .getAbsolutePath();绝对路径

    .lastModified();最后修改时间

    .length();文件大小,不能判断目录/文件夹

    .getParent();父路径,得到指定目录的前一级目录

    .getAbsoluteFile();得到文件绝对路径文件

    创建:

    .createNewFile();创建文件

    .mkdir();创建一层文件夹

    .mkdirs();创建多层文件夹

    File(String path)              通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例

    File(String path,String child) 根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。

    File(File file,String child)

list()                    返回一个字符串数组,这些字符串目录中的文件和目录。

list(FileNameFilter)      返回一个字符串数组,这些字符串指满足指定过滤器的文件和目录。

listFiles                 返回一个抽象路径名数组,这些路径名目录中的文件。

listFiles(FileNameFilter) 返回抽象路径名数组,这些路径名满足指定过滤器的文件和目录。

java 多线程

一、线程和进程

1、线程

注意:多线程。从宏观角度同时执行了多个线程。

             从微观角度同一时间只能执行一个线程

          多个线程是竞争关系,抢占 cpu 资源,否则只能等待。

2、进程和线程的区别

进程是应用程序,线程是一条执行路径

进程有独立的内存空间,崩溃不会影响其他程序,

线程没有独立的空间,多个线程在同一个进程的空间,可能会影响其他线程

一个进程中,至少有一个线程

3、创建线程的两种方式

1、创建一个类继承Thread

    2、重写run方法

    3、创建线程对象

    4、启动线程

    5Thread.currentThread().getName(),哪个线程调用,名字就是哪个现成的名字

      getName()super调用父类的getName(),被赋值谁的名字,就打印谁的名字

        

    main方法:

    Test2 test=new Test2("一号窗口");test.start();

        Test2 test2=new Test2("二号窗口");test2.start();

    

    class Test2 extends Thread{

        String name;

        int ticket=10;

         public Test2(String name) {

            super(name);

            this.name = name;

        }

        public void run() {

            while (true) {

                if (ticket>0) {

                    ticket--;

                    System.out.println(Thread.currentThread().getName()+"还剩下"+ticket);

                }else {

                    break;}

            }

        }

共享资源操作相同

1、共享资源类实现Runable接口

2、重写run方法

3、创建共享资源对象

4、创建线程对象,将共享资源对象添加到线程中

5、启动线程

    

    main方法:

    Test3 test3=new Test3();

    Thread thread=new Thread(test3);

    Thread thread2=new Thread(test3);

    thread.start();

    thread2.start();

    

    class Test3 extends Thread{

        String name;

        int ticket=10;

         public Test2(String name) {

            super(name);

            this.name = name;

        }

        public void run() {

            while (true) {

                if (ticket>0) {

                    ticket--;

                    System.out.println(Thread.currentThread().getName()+"还剩下"+ticket);

                }else {

                    break;}

            }

        }

贡献资源操作不相同

1、贡献资源作为一个单独的类

2、由多个操作去实现Runable接口

3、把共享资源作为多个操作类的属性

4、创建线程对象,将共享资源对象添加到线程中

5、启动线程

    

    main方法:

    Card card=new Card();

    Boyfriend boyfriend=new Boyfriend(card);

    Girlfriend girlfriend=new Girlfriend(card);

    Thread thread=new Thread(boyfriend);

    Thread thread2=new Thread(girlfriend);

    thread.start();

    thread2.start();

    class Card{

        double money;

    }

    class Boyfriend implements Runnable{

        Card card;

        public Boyfriend(Card card){

            this.card=card;

        }

        @Override

        public void run() {

        // TODO Auto-generated method stub

            for (int i = 0; i < 5; i++) {

                card.money+=500;

                System.out.println(Thread.currentThread().getName()+"存500-剩余金额"+card.money);

            }

        }

    }

    class Girlfriend implements Runnable{

        Card card;

        public Girlfriend(Card card){

            this.card=card;

        }

        @Override

        public void run() {

        // TODO Auto-generated method stub

            for (int i = 0; i < 5; i++) {

                card.money-=500;

                System.out.println(Thread.currentThread().getName()+"取500,剩余金额"+card.money);

            }

        }

    }

4、线程的五种状态

新建    就绪   执行   死亡  阻塞

Java 网络编程

1、IP 编程

    1、InetAddress,  没有构造方法,只能通过自己的静态方法创建对象

    2、getLocalHost(),   返回值是InetAddress,得到本机的主机名和地址

    3、getByName(ip),    返回值是InetAddress,有参数,可以写ip,网址,得到指定的主机

    4、getHostAddress(), 得到主机的地址

    5、getHostName(),    得到指定的主机名

2、TCP 编程

客户端:

        1、创建socket对象,指定ip地址和端口号

        2、需要从socket中得到OutputStream

            聊天配合字符流输入流使用,直接转换输入输出即可

            文件配合字节流使用,字节流读,socket输出。

        3、将想要发送的数据写入到OutputStream中。flush    

        4、关闭流关闭socket  

    服务器:

        1、创建ServerSocket对象,指定端口号

        2、serversocket.accep(),返回一个Socket对象(客户端发过来的socket)

         接收客户端发送的数据,如果没有接收到,阻塞程序的运行

        3、从Socket中得到InputStream流,将数据从流中读取出来

            聊天配合字符输出流使用。

            文件配合字节输出流使用,socket读,字节流输出。

        4、展示/写入到另外的地方

        5、关闭流,关闭Socket  

    聊天:

    聊天客户端:

        Socket socket=new Socket("127.0.0.1", 65499);

        OutputStream outputStream=socket.getOutputStream();

        BufferedWriter bufferedWriter=new BufferedWriter(new OutputStreamWriter(outputStream));

        InputStream inputStream=socket.getInputStream();

        BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));

        Scanner scanner=new Scanner(System.in);

        while (true) {

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

            String string=scanner.next();

            bufferedWriter.write(string);

            bufferedWriter.newLine();

            bufferedWriter.flush();

            if (string.equals("拜拜")) {

                break;

            }

            //接收数据

            String string2=null;

                string2=bufferedReader.readLine() ;

                System.out.println("服务器回复:"+string2);

                }  

        //关闭流和socket

    聊天服务器:

        ServerSocket serverSocket=new ServerSocket(65499);

        System.out.println("服务器等待中。。。");

        Socket socket=serverSocket.accept();

        InputStream inputStream=socket.getInputStream();

        Scanner scanner=new Scanner(System.in);

        BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));

        OutputStream outputStream=socket.getOutputStream();

        BufferedWriter bufferedWriter=new BufferedWriter(new OutputStreamWriter(outputStream));

        String string=null;

        while (true) {

         string=bufferedReader.readLine();

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

         if (string.equals("拜拜")) {

                break;

            }

         System.out.println("服务器回复:");

         String string2=scanner.next();

         bufferedWriter.write(string2);

         bufferedWriter.newLine();

         bufferedWriter.flush();

        }

        //关闭各种流和socket等

3、UDP 编程

客户端:

        1、创建套接字对象,DatagramSocket,不需要指定端口号和地址

            (聊天配合字符输入流),文件配合字节输入流

        2、创建数据报包对象DatagramPacket,使用四个参数,指定数据,数据长度,地址,端口号。

        3、send发放发送数据

        4、关闭socket

    服务器:

        1、创建套接字对象DatagramSocket,指定端口号

        2、创建数据报包对象DatagramPacket,用两个参数的。指定数据和数据长度。

        3receice()接收数据,如果接受不到,阻塞程序。

        4、根据数据报包进行一系列需要的操作

    聊天:

    客户端:

        DatagramSocket datagramSocket=new DatagramSocket();

        BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in));

        while (true) {

            System.out.println("客户端--:");

            String string2=bufferedReader.readLine();

            DatagramPacket datagramPacket=new DatagramPacket(string2.getBytes(), string2.getBytes().length, InetAddress.getLocalHost(),65496);

            datagramSocket.send(datagramPacket);

            if (string2.equals("拜拜")) {

                break;

            }

        byte []buf=new byte[1024];

        DatagramPacket datagramPacket2=new DatagramPacket(buf, buf.length);

        datagramSocket.receive(datagramPacket2);

        String string=new String(datagramPacket2.getData(), 0, datagramPacket2.getLength());

        System.out.println("服务器--"+string);

        }

    服务器:

        DatagramSocket datagramSocket = new DatagramSocket(65496);

        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));

        System.out.println("客户端已准备");

        byte[] buf = new byte[1024];

        while (true) {

            DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length);

            datagramSocket.receive(datagramPacket);

            String string = new String(datagramPacket.getData(), 0, datagramPacket.getLength());

            if (string.equals("拜拜")) {

                break;

            }

        System.out.println("我说~~"+string);

        //回复数据

        System.out.println("你说~~:");

        String string3 = bufferedReader.readLine();

        DatagramPacket datagramPacket2 = new DatagramPacket(string3.getBytes(), string3.getBytes().length,

                InetAddress.getLocalHost(), datagramPacket.getPort());

        if (string3.equals("拜拜")) {

            break;

        }

        datagramSocket.send(datagramPacket2);

        }

数据库语句

固定语句:

    Class.forName("org.sqlite.JDBC");加载驱动

            Connection connection=DriverManager.getConnection("jdbc:sqlite:/e:/SQLite/day0919-1.db");创建连接       

    Statement statement=connection.createStatement();创建执行sql语句的对象

     1、创建表 create table [if not exists] tablename(_id integer primary key autoincrement,name vachar(15)....);

     2、追加列 alter table tablename add 字段名 integer

     3、插入数据 insert into tablename(id,name...)values(1,'aa');

     4、查询数据 select * from tablename where name='aa';    

     5、修改数据 update tablename set name='aa' where name='aa';

     6、删除数据 delete from tablename where name='aa'

     7、模糊查询 select * from tablename where name like '%aa%';

     8、升序     select * from employees order by id ;

     9、降序     select * from employees order by id desc;

     10、多字段  select * from employees order by department_id desc,salary asc;

     11、and or   

     执行语句: statement        用于查询(executequery)删除(executeupdate)修改(executeupdate)

                preparastatement 用于插入(executeupdate)

    注意:insert into tablename(id,name...)values(?,?,?...);

          preparedStatement.setString(1, id);//用占位符的时候需要prepareStatement设置

数据解析

一、XML 解析

  1. Dom 解析
Dom:先将整个文档全部加载在内存中,然后以树的结构去解析

        优点:解析速度快

        缺点:浪费内存
  1. Sax 解析
Sax:根据结点去解析,不会将这个文档全部加载内存中

       优点:区分文档开始、标签开始、数据、标签结束、文档结束

       缺点:不会记录读取到哪一个标签,需要自己标记

栗子:
        SAXParserFactory factory=SAXParserFactory.newInstance();

        SAXParser parser=factory.newSAXParser();

        MyHandler myHandler=new MyHandler();

        parser.parse("student2.xml",myHandler);

        List<Student> list=myHandler.result();

    MyHandle

            List<Student> students=null;

            Student student=null;

            String tag="";

            public  List<Student> result(){

            return students;

            }

            @Override

            public void startDocument() throws SAXException {

            students=new ArrayList<>();

            }

            @Override

            public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

            //qName当前解析的标签

            //开始标签

            tag=qName;

            if ("student".equals(qName)) {

            student=new Student();

            //标签内有多个属性时

            //int count=attributes.getLength();

            //for (int i = 0; i < count; i++) {

            //String name=attributes.getQName(i);

            //String value=attributes.getValue(i);

            //if ("id".equals(name)) {

            //student.setId(Integer.parseInt(value));

            //}

            //}

            //标签内只要一个属性时

            student.setId(Integer.parseInt(attributes.getValue(0)));

    

            }

            }

            @Override

            public void endElement(String uri, String localName, String qName) throws SAXException {

            // TODO Auto-generated method stub

            //遇到结束标签进入

            if ("student".equals(qName)) {

            students.add(student);

                }

            tag="";

            }

            @Override

            public void endDocument() throws SAXException {

            // TODO Auto-generated method stub

            super.endDocument();

            }

            @Override

            public void characters(char[] ch, int start, int length) throws SAXException {

            // TODO Auto-generated method stub

            String count=new String(ch, start, length).trim();

            if ("id".equals(tag)) {

                student.setId(Integer.parseInt(count));

            }else if ("name".equals(tag)) {

                student.setName(tag);

            }else if ("age".equals(tag)) {

                student.setAge(Integer.parseInt(count));

            }else if ("sex".equals(tag)) {

                student.setSex(count);

            }

            }

3、Pull 解析

        1、得到pull解析对象的工厂对象

           XmlPullParseFactory factory=XmlPullParseFactory.newInatance();

        2、通过工厂对象得到解析对象

           XmlPullParse parse=factory.newPullParse();

        3、设置解析数据源

           parse.setInput(new FileReader(".xml"));

        4、设置解析文件中事件的状态

           int type=parse.getEventType();

        5、存放解析结果的集合

           Lst<Student> student=null;

        6、声明解析对象

           Student student=null7、判断状态,根据状态取得数据。

           if(type!=XmlPullParse.END_DOCUMENT){

            switch(type){

            case XmlPullParse.START_DOCUMENT:

                student=new ArrayList<>();

                break;

            case XmlPullParse.START_TAG:

                if("student".queals(parser.getName())){

                    student=new Student();

                    }else if("id".equals(parse.getName()))

                        String id=parse.nextInt();

                        student.setId(Integer.parseInt(id));    

                        ......              

                }   }

        8、事件的状态进行下一个

            type=parse.next();

            }

        9、若标签中有很多属性

            int count=parser.getAttributeCount();

                for (int i = 0; i <count; i++) {

                    String arrName=parser.getAttributeName(i);

                    String arrValue=parser.getAttributeValue(i);

                    if ("id".equals(arrName)) {

                        student.setId(Integer.parseInt(arrValue));

                    }

二、JSON 解析

  1. JSON
1、对象    JSONObject jsonObject=new JSONObject(string);

2、数组    JSONArray jsonArray=new JSONArray(string);

3、对象里对象 JSONObject jsonObject2=jsonObject.getJSONObject("dept");

4、对象里数组 JSONArray jsonArray=jsonObject.getJSONArray("persons"); 

例子:

    String string="{persons:[{name:'zhangsan',age:20},{name:'lisi',age:21},{name:'wangwu',age:22}]}";

    JSONObject jsonObject=new JSONObject(string);

    JSONArray jsonArray=jsonObject.getJSONArray("persons");

    List<Person3> list=new ArrayList<>();

    for (int i = 0; i < jsonArray.length(); i++) {

        JSONObject jsonObject2=jsonArray.getJSONObject(i);

        String name=jsonObject2.getString("name");

        int age=jsonObject2.getInt("age");

        Person3 person3=new Person3(name, age);

        list.add(person3);      

    }

    for (Person3 person3 : list) {

        System.out.println(person3);

            }

        }

        }

    class Person3{

        String name;

        int age;

        public Person3(String name, int age) {

            super();

            this.name = name;

            this.age = age;

        }

        @Override

        public String toString() {

            return "person2 [name=" + name + ", age=" + age + "]";

        }
    }
  1. Gson
Gson gson=new Gson();

    Person6 person6=gson.fromJson(string, Person6.class);

例子:

    String string = "{no:1,name:'android',employees:[{name:'zhangsan',age:20},{name:'lisi',age:21},{name:'wangwu',age:22}]}";

    Gson gson=new Gson();

    Person6 person6=gson.fromJson(string, Person6.class);

    System.out.println(person6);}

    }

    class Person5{

        @Override

        public String toString() {

        return "Person5 [name=" + name + ", age=" + age + "]";

        }

        String name;

        int age;

    }

    class Person6

    {

        int no;

        String name;

        ArrayList<Person5> employees;

        @Override

        public String toString() {

            return "Person6 [no=" + no + ", name=" + name + ", employees=" + employees + "]";

        }
  1. FastJson
Person4 person4=JSON.parseObject(string, Person4.class);

例子:

    String string = "{no:1,name:'android',employees:[{name:'zhangsan',age:20},{name:'lisi',age:21},{name:'wangwu',age:22}]}";

    Person4 person4=JSON.parseObject(string, Person4.class);

    System.out.println(person4);

        }

    }

class Person3{

    String name;

    int age;

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public int getAge() {

        return age;

    }

    public void setAge(int age) {

        this.age = age;

    }

    @Override

    public String toString() {

        return "Person3 [name=" + name + ", age=" + age + "]";

        }



}

class Person4{

int no;

String name;

ArrayList<Person3> employees;

public int getNo() {

    return no;

}

public void setNo(int no) {

    this.no = no;

}

public String getName() {

    return name;

}

public void setName(String name) {

    this.name = name;

}

public ArrayList<Person3> getEmployees() {

    return employees;

}

public void setEmployees(ArrayList<Person3> employees) {

    this.employees = employees;

}

@Override

public String toString() {

    return "Person4 [no=" + no + ", name=" + name + ", employees=" + employees + "]";

}
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kevin-Dev

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值