java学习笔记


@Author: sabot
@Date:2019-07-24


文章目录

    • 基础语法
          • 1.数据类型
          • 2.运算符
          • 3.快捷键
          • 4.方法
    • 面向对象与封装
          • 1.局部变量与成员变量
          • 2.封装
          • 3.private关键字
          • 4.this关键字
          • 5.构造方法
          • 6. Java Bean
    • 常用API第一部分
          • 1.引用类型的使用步骤
          • 2.Scanner类
          • 3.匿名对象
          • 4.Random类
          • 5.ArrayList集合
          • 5.String类
          • 6.static关键字
          • 7.Arrays数组工具类
          • 8.Math数学工具类
    • 继承与多态
          • 1.继承
          • 2.抽象类
          • 3.接口
          • 4.多态
          • 5.final关键字
          • 6.权限修饰符
          • 7.内部类
    • 常用API第二部分
          • 1.Date类
          • 2.Calender类
          • 3.System类
          • 4.Strinngbuilder
          • 5.包装类
    • 集合
          • 1.Collection集合
          • 共性常用方法
          • 2.List集合
          • 3.Set集合
          • 4.Collections集合工具类
          • 5.Map集合
    • 多线程
          • 1.创建多线程的方法
          • 2.线程安全问题
          • 3.线程状态
          • 4.Lambda表达式
    • File类与IO流
          • 1.File
          • 2.io流
    • 网络编程
    • JDK8新特性
          • 1.函数式接口
          • 2.stream流
          • 3.方法引用
    • 反射

基础语法

1.数据类型
  • javac +文件名+后缀名 -> 编译 java + 文件名 ->运行
  • 浮点数默认是 double 类型,要设置为 float 可在数值末尾加是 F 后缀
  • byte/short/char 在进行运算时会先提升为int 类型
  • boolean 类型不能发生任何数据类型转换
  • ASCLL码: 0->48, A->65 , a->97
2.运算符
  • 比较运算符的结果是一个布尔值,ture or false
  • 逻辑运算符具有短路效果
  • 三目运算符,? :
3.快捷键
  • ctrl+D 快速复制粘贴一行代码,出现在该行代码下一行
  • ctrl+Y 快速删除一行代码,可连续删除
  • ctrl+Z 取消操作,回滚
  • ctrl+X 剪切
  • alt+回车 导包或添加变量
  • alt+insert 添加get set toString 等
  • shift+F6 鼠标指向一个类文件,重命名
  • ctrl+/ 单行注释,注释或取消
  • ctrl+shift+/ 多行注释
  • ctrl+alt+T 选定代码块 surround with
  • Alt+Shift+F10,选择 Run
  • ctrl+Alt+L 格式化代码
  • Alt+Shift+Up/Down 上/下移一行
  • Ctrl+Enter 上插一行
  • Shift+Enter 向下插入新行
4.方法
  • 方法重载:名称相同,参数列表不同。{个数或类型或多类型顺序不同)与返回值类型无关

面向对象与封装

1.局部变量与成员变量

1.定义位置不同:

局部变量:方法内部

成员变量:方法外部,直接定义在类中

2.作用范围不同

局部变量:只在该方法内部可使用

成员变量:整个类都可以使用

3.默认值不同

局部变量:没有默认值,使用前必须主动赋值

成员变量:null 或 0.0

4.内存位置不同

局部变量:栈内存

成员变量:堆内存

5.生命周期不同

局部变量:随方法进栈而诞生,随方法出栈而消失

成员变量:随对象创建而诞生,随对象被垃圾回收而消失

2.封装

将一些细节信息隐藏起来对外界不可见

1.方法是一种封装

2.关键字private也是一种封装

3.private关键字

问题描述:定义person的年龄时,无法阻止不合理数值被设置

解决方案:用private关键字进行修饰保护成员变量

使用了private进行修饰本类中任然可以任意访问,但其他类不可以直接访问。

间接访问使用Getter/Setter方法

对于基本数据类型的boolean 的Getter方法要写成isXxx

4.this关键字

当方法的局部变量与类成员变量重名的时候,根据“就近原则”,优先使用局部变量。如果需要访问本类当中的成员变量时,使用格式:

this.成员变量

通过谁调用方法,谁就是this

5.构造方法

专门用来创建对象的方法,当我们通过关键字new来创建对象时,其实是调用了构造方法。

格式:

public 类名称(参数类型 参数名称){

方法体

}

注意事项:

1.构造方法名称与类名称完全相同

2.构造方法不要写返回值,连void都不要写

3、构造方法不能return一个具体的返回值

4.默认会有一个无参的构造方法

5.但自己编写一个构造方法后,将不再会有默认的无参构造方法

6. Java Bean

一个标准的类通常用友下面四个部分:

1.所有成员变量都使用private关键字修饰

2.为每一个成员变量编写一对Getter/Setter方法

3.编写一个无参构造方法

4.编写一个全参构造方法

这样标准的类也叫做 Java Bean

常用API第一部分

1.引用类型的使用步骤

1.导包

import 包路径.类名称

如果需要使用的目标类和当前类在同一包下,则可以不写。

java.lang 包下的内容不需要导包

2.创建

类名称 对象名 = new 类名称();

3.使用

对象名.成员方法();

2.Scanner类
import java.util.Scanner;

/**
 * @auther:sabot
 * @date:2019/06/10
 * @description:使用Scanner类从键盘获取输入
 */
public class A1_Scanner {

    public static void main(String[] args) {

        //System.in 代表从键盘输入
        Scanner sc =new Scanner(System.in) ;

        //获取一个int值
        int num = sc.nextInt();
        System.out.println("输入的数值是"+num);

        //获取一个String字符串
        String str = sc.next();
        System.out.println("输入的字符串是"+str);
    }
}
3.匿名对象

当确定一个对象只需要使用一次,则可以使用匿名对象

可以作为参数也可以作为返回值

4.Random类

Random类用来生成随机数字

获取一个随机int数字(范围是int所有范围,有正负):

Random r = new Random();//小括号留空
int num = r.nextInt();

小括号内代表范围

int num = r.nextInt(10)

左开右闭:[ 0 , 1 0)。

float num = r.nextFloat()

[0,1)

5.ArrayList集合

长度可变的一个容器,存储对象

代表泛型,泛型只能是引用类型,不能是基本类型

注意事项:直接打印ArrayList得到的不是地址值,而是其中的内容。如果为空,则是 [].

//创建一个ArrayList集合
//备注:从JDK1.7开始,右侧<>内容可省略
ArrayList<String>  list = new ArrayList<>();
System.out.println(list); //[]

//向集合添加数据
list.add("Iron man");
list.add("superman");
System.out.println(list);//[Iron man,surperman]

1.常用方法及遍历ArrayList:

import java.util.ArrayList;

/**
 * @auther:sabot
 * @date:2019/06/12
 * @description:
 *      常用方法:
 *          public boolean add( E e ); 向集合中添加元素,参数类型和泛型一致,返回值代表是否成功
 *          public E get(int index); 从集合中获取元素参数是索引编号,返回对应元素。
 *          public E remove(int index); 从集合中删除元素,参数是索引,返回值就是被删除的元素
 *          public int size(); 获取集合的长度
 *      遍历集合。
 *
 */

public class A6_ArrayListMethod {

    public static void main(String[] args) {
        ArrayList<String>  list = new ArrayList<>();
        System.out.println(list);//[]

        //向集合添加元素
        boolean result = list.add("superman");
        System.out.println(result);   //true

        for (int i = 1; i < 10; i++) {
            list.add("person"+i);
        }
        System.out.println(list);

        //从集合中获取元素,索引从0开始
        String name = list.get(0);

        //从集合中删除元素
        String whoRemove = list.remove(0);
        System.out.println("0号元素:  "+name+"   ,删除0号:"+whoRemove);

        //获取集合长度,即集合中的元素个数
        System.out.println("集合长度: "+list.size());

        //遍历集合
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }

}

2.在ArrayList中加入基本数据类型

import java.util.ArrayList;

/**
 * @auther:sabot
 * @date:2019/06/12
 * @description:如果希望像集合ArrayList中储存基本数据类型,必须使用对应的包装类
 *
 * 基本类型         包装类(引用类型  位于java.lang包下
 * byte                Byte
 * short               Short
 * int                 Integer   【特殊】
 * long                Long
 * float               Float
 * double              Double
 * char                Character  【特殊】
 * boolean             Boolean
 */
public class A7_ArrayListBasic {

    public static void main(String[] args){

        ArrayList<Integer> list = new ArrayList<>();
        list.add(10);

        int num = list.get(0);
        System.out.println(num);
    }
}
5.String类

java.lang.String类代表字符串

Java程序中所有的字符串字面值(如“abc”)都作为此类的实例实现

1.字符串的特点:

  • 字符串的内容永不可变【重点】
  • 正是因为不可改变,所以字符串是可以共享使用的
  • 字符串的效果相当于char[]字符数组,但其底层原理是byte[]字节数组

2.字符串的构造方法及直接创建

/**
 * @auther:sabot
 * @date:2019/06/13
 * @description:
 *          三种构造方法:
 *             public String(): 创建一个空白字符串,不包含任何内容
 *             public String(char[] array): 根据字符数组的内容创建对应的字符串
 *             public String(byte[] array): 根据字节数组的内容创建对应的字符串
 *          一种直接创建:
 */
public class AB_String {

    public static void main(String[] args) {

        //空参构造
        String str1 = new String();
        System.out.println("第一个字符串:"+str1);

        //根据字符数组创建
        char[] charArray = {'a','b','c'};
        String str2 = new String(charArray);
        System.out.println("第二个字符串: "+str2);

        //根据字节数组创建
        byte[] byteArray = { 97,98,99 };
        String str3 = new String(byteArray);
        System.out.println("第三个字符串: "+str3);

        //直接创建
        String str4 = "ABC";
        System.out.println("第四个字符串: "+str4);
    }
}

3.字符串常量池

/**
 * @auther:sabot
 * @date:2019/06/13
 * @description:
 *      字符串常量池:程序中直接创建的双引号字符串就在字符串常量池中。
 *      " == " : 对于基本类型是进行数值比较,对于引用类型是进行【地址值】比较
 */
public class AC_StringPool {

    public static void main(String[] args) {

        String str1 = "ABC";
        String str2 = "ABC";

        char[] charArray = { 'A','B','C'};
        String str3 = new String(charArray);

        System.out.println(str1 == str2);  //true
        System.out.println(str1 == str3);  //false
        System.out.println(str2 == str3);  //false
    }
}

4.equals方法比较内容,equalsIgnoreCase方法忽略大小写

5.String类的常用转化方法

/**
 * @auther:sabot
 * @date:2019/06/14
 * @description:
 *  String类当中常用的装换方法:
 *      public char[] toCharArray(): 将当前字符串转化为字符数组返回。
 *      public byte[] getBytes(): 获取当前字符串底层的字节数组返回。
 *      public String replace(CharSequence oldString, CharSequence newString):
 *      将所有出现的老字符串替换成新字符串返回
 */
public class AE_StringConvert {

    public static void main(String[] args) {
        //转化成字符数组
        char[] chars = "hello".toCharArray();
        System.out.println(chars.length);

        //转化成字节数组
        byte[] bytes = "abc".getBytes();
        for (int i = 0; i < bytes.length; i++) {
            System.out.println(bytes[i]);
        }

        //字符串替换
        String Str = "会不会玩呀!你大爷的。";
        System.out.println(Str.replace("你大爷的","****"));
    }
}

6.split分割方法

/**
 * @auther:sabot
 * @date:2019/06/14
 * @description:
 *  字符串分割方法:
 *          public String[] split(String regex): 按照参数的规则分割成若干部分
 *
 *  注意事项:split参数是正则表达式,如果以"."作为参数,要写成"\\."
 */
public class AF_StringSplit {

    public static void main(String[] args){

        String str1 ="superman,Iron man,Thor";
        String[] split = str1.split(",");
        for (int i = 0; i < split.length; i++) {
            System.out.println(split[i]);
        }
    }
}
6.static关键字

1.当成员变量使用了static关键字,它将成为属于类,所有对象共用一份数据

2.当成员方法使用了static关键字修饰,其将成为静态方法,不需要创建对象,也可以使用

类名.方法名

调用

3.注意事项:

  • ​ 静态不能直接访问非静态【先人呢不知道后人】
  • ​ 推荐使用类名称加方法名访问静态成员或方法
  • ​ 静态方法中不能使用this关键字

4.静态代码块

public class 类名称{
	static{
		//内容
	}
}

特点:第一次用到本类时,静态代码块执行唯一一次,优先于构造方法执行

用途:一次性的对静态成员变量进行赋值

7.Arrays数组工具类
package a3_api01;
import java.util.Arrays;
/** * @auther:sabot 
* @date:2019/07/05 
* @description: java.util.Arrays是一个于数组相关的工具类,提供了大量静态方法实现数组的常见操作 
* 

* public static String toString(数组) * public static void sort(数组),排序,由小到大 */ public class B3_Arrays { public static void main(String[] args) { int[] intarray = {10, 20, 30, 40, 1, 45, 21}; System.out.println(Arrays.toString(intarray)); Arrays.sort(intarray); System.out.println(Arrays.toString(intarray)); } }

8.Math数学工具类
/** 
* @auther:sabot
* @date:2019/07/06 
* @description:java.util.Math是与数学相关的工具类,提供大量静态方法完成与数学相关的操作 
*
* public static double abs(double num):获取绝对值
* public static double ceil(double num):向上取整
* public static double floor(double num):向下取整
* public static double round(double num):四舍五入
* 
* Math.PI代表圆周率的近视值 
*/
public class B4_Math {   
    public static void main(String[] args) {
        System.out.println(Math.abs(-12.234));  //12.234        
        System.out.println(Math.ceil(-12.234)); //-12.0        
        System.out.println(Math.floor(-12.234));//-13.0        
        System.out.println(Math.round(-12.234));//-12      
        System.out.println(Math.PI);            //3.141592653589793  
    }
}

继承与多态

1.继承

面向对象的三大特性:封装,继承,多态,继承是多态的前提,继承主要解决的问题是共性抽取,子类可以拥有父类的内容也可以拥有自己的内容。

设计原则:对于已经投入使用的类,尽量不要修改。推荐使用一个新的类,来重复利用其中的共性内容,并增加新内容,即继承

  • 继承中变量重名的应用方法:

    局部变量:直接写变量名

    子类中的成员变量:this.变量名

    父类中的成员变量:super.变量名

  • 继承中的方法重写:

    重写(override):名称与参数列表都相同

    重载(overload):名称相同,参数列表不同

    注意事项:

    1. @Override写在方法前可用来检测是否是正确的有效重写
    2. 子类的返回值必须小于或等于父类
    3. 子类的权限必须大于或等于父类(public > protected > default > private)
  • 继承中的构造方法的访问特点:

    1. 子类构造方法使用一个隐含的super();调用,所以一定是先使用父类构造,再使用子类构造
    2. 子类可以通过super关键字调用父类的重载构造方法
    3. super的父类构造调用必须是子类构造方法的第一个语句,一个子类构造方法不能多次调用super构造
  • 继承中super关键字的用法

    1. 在子类成员方法中,访问父类的成员变量或成员方法
    2. 在子类构造方法中访问父类构造方法
  • java是单继承,但可以多级继承。

2.抽象类
/** 
* @auther:sabot 
* @date:2019/07/10 
* @description: 
*  抽象方法:用abstract关键字修饰,去掉大括号 
*  抽象类: 抽象方法所在的类必须是抽象类,class前用abstract修饰 
*
*  如何使用抽象类: 
*  1.不能直接创建new抽象类对象 
*  2.必须使用一个类继承抽象类,并覆盖重写父类中的抽象方法。 
*  覆盖重写(实现):子类去掉抽象方法中的abstract关键字,补上方法体 
*/
public abstract class animal {    
    //抽象方法   
    public abstract void eat();  
    //普通方法   
    public void sleep(){ 
        System.out.println("睡觉"); 
    }
}
3.接口

接口是类的公共规范,是一种应用数据类型

格式:

public interface 接口名称{
	//接口内容
}

其中包含的内容有:

1.常量

2.抽象方法

3.默认方法 (java8)

4.静态方法

5.私有方法(java9)

  • 使用步骤

    1. 定义一个实现类来实现接口

    2. 格式:

      public class 实现类名称 implements 接口名称{
      	//...
      }
      
    3. 实现类必须覆盖重写所有抽象方法,否则其本身为抽象类

  • 接口默认方法

    从java8开始,接口允许定义默认方法。格式:

    public default 返回值类型 方法名称(参数列表){
    	方法体
    }
    

    默认方法可解决接口升级问题。可直接通过接口实现类对象调用,也可以被接口实现类覆盖重写。

  • 接口静态方法

    从java8开始,接口允许定义默认方法。格式:

    public static 返回值类型 方法名称(参数列表){
    	方法体
    }
    

    所有实现类共享的,可直接通过接口名称调用

  • 接口私有方法

    1. 普通私有方法解决多个默认方法之间的代码重复问题,格式:

      private 返回值类型 方法名称(参数列表){
      	方法体
      }
      
    2. 静态私有方法解决多个静态方法之间的代码重复问题,格式:

      private static 返回值类型 方法名称(参数列表){
      	方法体
      }
      
  • 接口中常量

    接口中也可以定义成员变量,但必须使用public static final 三个关键字修饰

    从效果上看,实际上这就是接口的【常量】,格式:

    public static final 数据类型 常量名称 = 数据值

    注意事项:

    1. 使用final关键字进行修改说明其不可改变
    2. 接口中的常量必须进行赋值
    3. 常量名称应全大写
  • 接口的注意事项

    1. 接口中没有静态代码块或构造方法
    2. 一个类可实现多个接口
    3. 实现的多个接口中若存在重复的抽象方法,覆盖重写一次即可
    4. 实现类没有覆盖所有接口中的所有抽象方法,则其为抽象类
    5. 存在重复的默认方法,实现类应进行覆盖重写
    6. 类的父类和接口中的默认方法产生冲突,优先使用父类的方法
    7. 接口之中存在多继承
4.多态

extends继承与implements实现是多态性的前提,一个对象具有多种形态。

多态的好处在于:无论实例化的是哪种子类对象,等号左边调用方法都不会变,都可以写成父类。

  • 代码中多态性的体现

    父类引用指向子类对象。格式:

    父类名称 对象名 = new 子类名称();
    //或者
    接口名称 对象名 = new 实现类名称();
    
  • 多态中成员变量的两种方式

    1.直接通过对象名称访问成员变量:看等号左边是谁,没有则向上寻找。

    2.间接通过成员方法访问成员变量:看方法属于谁,没有则向上寻找。

  • 多态中成员方法访问规则

    看new谁,new谁用谁,没有则向上寻找。

  • instanceof

    格式:对象名 instanceof 类名称

    判断对象是不是该类,返回Boolean值

5.final关键字

代表最终的,不可变的,可修饰类,方法,局部变量,成员变量。

  1. 修饰一个类时,该类不能拥有任何子类
  2. 对于类或方法,final和abstract不能同时使用
  3. final修饰成员变量,由于其默认值为0,则必须手动赋值。
6.权限修饰符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j4aSZVYS-1583461276902)(C:\Users\sabot\Pictures\Saved Pictures\Snipaste_2019-07-12_15-52-03.png)]

7.内部类

成员内部类,局部内部类(包含匿名内部类)

注意:内用外,随意使用,外用内,需要对象

  • 成员内部类的使用

    直接:在外部类的方法中使用内部类

    间接:公式

    `外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();

    变量重名时,内部类通过 外部类名称.this.变量名 访问外部类成员变量

  • 匿名内部类

    如果接口的实现类只需要使用一次,则可以省略该类的定义,使用匿名内部类。

    格式:

    接口名称 对象名 = new 接口名称(){
    	//覆盖重写所有抽象方法
    };![Snipaste_2019-07-14_17-00-09](D:\学习资源\JPG\snipaste\Snipaste_2019-07-14_17-00-09.png)
    

常用API第二部分

1.Date类
  • 构造方法

    Date(long date); 传递毫秒值,把毫秒值转换为Date日期

    Date(); 空参构造方法 ,获取当前系统日期和时间

  • 成员方法

    long getTime();把日期转化为毫秒值(相当于System.currentTimeMillis();方法),返回自1970年1月1日00:00:00GMT至今的毫秒数

  • DateFormat

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qSVeTVN6-1583461276904)(D:\学习资源\JPG\snipaste\Snipaste_2019-07-14_17-00-09.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g0OSM6EQ-1583461276906)(D:\学习资源\JPG\snipaste\Snipaste_2019-07-14_17-00-45.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0DAWv3Xq-1583461276907)(D:\学习资源\JPG\snipaste\Snipaste_2019-07-14_17-00-50.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CFDqZpqw-1583461276909)(D:\学习资源\JPG\snipaste\Snipaste_2019-07-14_17-00-54.png)]

2.Calender类
import java.util.Calendar;
/** 
* @auther:sabot 
* @date:2019/07/14
* @description:java.util.Calender类:日历类 
*  Calender是一个抽象类,提供了操作日历字段的方法,其无法直接创建对象使用。
*  使用静态方法getInstance(),该方法返回Calender子类。
*/public class Calender01 {  
    public static void main(String[] args) {   
        Calendar c = Calendar.getInstance();//多态   
        System.out.println(c);     
        c.get(Calendar.YEAR); 
    }
}
3.System类
/** 
* @auther:sabot
* @date:2019/07/14
* @description:java.util.System类提供了大量静态方法,可以获取与系统相关的信息及系统级操作 常用方法: * public static long currentTimeMills(); 返回当前时间的毫秒值 
* public static void arraycopy(object src ,int srcpos, object dest ,int desrpos, int length):拷贝数组的指定元素 
*/public class System_class {  
    public static void main(String[] args) {   
        long begin = System.currentTimeMillis();       
        System.out.println(begin);     
        int[] src = {1, 2, 3, 4, 5};     
        int[] dest = {6, 7, 8, 9, 0};    
        int j = 1;    
        System.arraycopy(src, 0, dest, 0, 3);   
        for (int i = 0; i < 9999; i++) {      
            j++;     
        }       
        System.out.println(System.currentTimeMillis()-begin);  
    }
}
4.Strinngbuilder

字符串缓冲区,可修改字符串。append方法修改,toString方法转化为String.

5.包装类
public class Integer01 { 
    public static void main(String[] args) {    
        //装箱       
        Integer in1 = new Integer(12);   
        System.out.println(in1);    
        Integer in2 = Integer.valueOf(12);     
        System.out.println(in2);     
        //拆箱   
        int i = in1.intValue();    
        System.out.println(i);    
        //自动装箱    
        Integer i = 1;       
        //自动拆箱      
        int a = i + 2;   
        //基本类型 ->String     
        System.out.println(String.valueOf(10));  
        //String -> 基本类型 
        int b = Integer.parseInt("12");     
    }
}

集合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ezQpucEc-1583461276911)(D:\学习资源\JPG\snipaste\Snipaste_2019-07-15_14-17-10.png)]

1.Collection集合
  • 共性常用方法
public boolean add( E e ); //添加元素
public void clear( );  //清空元素
public boolean remove( E e );  //移除给定元素
public boolean contains( E e );  //判断元素是否属于集合
public int size() : // 返回集合中元素的个数
public Object[] toArray():  //把集合中元素存储到数组中
  • Iterator迭代器

    java.util.Iterator接口(对集合进行遍历),使用步骤:

    1. 使用集合中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接受(多态)
    2. 使用Iterator接口中的hasNext()方法判断是否还有下一个对象
    3. 使用next方法取出集合的下一个元素
    public class a1_Iterator { 
        public static void main(String[] args) {    
            Collection<String> it = new ArrayList<>();     
            it.add("Stack");   
            it.add("Thor");   
            it.add("Hock");   
            it.add("Mei"); 
            
            Iterator<String>  iterator =  it.iterator(); 
            
            while(iterator.hasNext()){        
                System.out.println(iterator.next()); 
            }  
            
            System.out.println(it); 
        }
    }
    
  • 增强型for循环

    格式:

    for(集合/数组的类型  变量名 : 集合名/数组名){
    	//...
    }
    
    public class a2_For2 {  
    	public static void main(String[] args) {  
         	Collection<String> it = new ArrayList<>();   
            it.add("Stack");     
            it.add("Thor");   
            it.add("Hock");     
            it.add("Mei");   
            for (String i : it) {       
                System.out.println(i);    
            }     
            System.out.println(it);  
        }
    }
    
2.List集合
  • 特点:

    1. 有序
    2. 有索引(查询快修改慢)
    3. 允许重复
  • 常用方法:

    public void add(int index, E element):添加元素到指定位置
    public E get(int index): 获取指定位置上的元素
    public E remove(int index):移除指定位置上的元素并返回
    public E set(int index, E element):替换指定元素
    

    操作是应防止索引越界

  • LinkedList:

    底层是链表结构(查询慢,修改快),包含了大量操作首位的方法。

    注意使用LinkedList特有方法时不能使用多态

    package a6_collection;
    import java.util.LinkedList;
    /** * @auther:sabot 
    * @date:2019/07/17 
    * @description:java.util.LinkedList 
    * 
    * public void addFirst( E e ):将指定元素插入列表头
    * public void addLast( E e ):将指定元素插入列表尾 
    * public void push( E e ): 相当于addFirst 
    * 
    * public E getFirst(); 返回第一个元素 
    * public E getLast(); 返回最后一个元素 
    *
    * public E removeFirst(); 移除并返回第一个元素 
    * public E removeLast(); 移除并返回最后一个元素
    * public E pop(); 相当于removeFirst
    *
    * public boolean isEmpty(); 检查列表是否为空 
    * 
    */
    public class a4_LinkedList {  
        public static void main(String[] args) {  
            LinkedList<String> link = new LinkedList<>();   
            link.add("i"); 
            link.add("am");   
            link.add("Iron");   
            link.add("man");   
            System.out.println(link);       
        }
    }
    
3.Set集合
  • 特点:

    1. 不允许重复
    2. 没有索引,不能使用普通for循环遍历
    3. 无序
  • HashSet

    底层是一个哈希表结构(查询快)

    public class a5_Set { 
        public static void main(String[] args) {  
            Set<Integer> it = new HashSet<>();    
            it.add(12);     
            it.add(13);  
            it.add(14);      
            it.add(12);  
            System.out.println(it);  //[12, 13, 14]  
        }
    
    }
    
  • 哈希值

    哈希值是一个十进制整数,由系统给出,是对象的模拟地址值。

    int hashCode();返回对象的哈希值

  • 哈希表:数组+链表/红黑树

  • 用HashSet存储自定义元素时记得重写equals,HashCode方法

  • LinkedHashSet:底层是一个哈希表+链表(记录元素存储顺序,,保证元素有序)

  • 可变参数:格式:数据类型 ... 变量名称

    例如:public int add( int ... arr)

    一个方法只能·有一个可变参数,且放在参数列表最后

4.Collections集合工具类

java.utils.Collections是集合工具类,提供了对集合操作的方法

  1. public static boolean addAll(Collection c, T...elements):往集合中添加元素

  2. public static void shuffle(List<?> list)打乱集合中元素顺序

  3. public static void sort(List List)将集合元素按默认规则排序

    被排序的集合中的元素必须实现Comparable接口,重写compareTo方法

  4. public static void sort(List list,Comparator)将集合元素按指定规则排序

5.Map集合

java.util.Map集合

  1. Map集合是一个双列集合,一个元素包含两个值(key,value)
  2. key不允许重复
  • 常用方法

    package a6_collection;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;import 
        java.util.Set;public class a7_HashMap {  
            public static void main(String[] args) {  
                Map<Integer,String> map = new HashMap<>();  
                
                //添加元素    
                String str1 = map.put(1,"Iron man"); 
                map.put(2,"Thor");      
                map.put(3,"super man");   
                map.put(4,"spider man");   
                System.out.println(str1);  //null 
                
                //移除元素      
                String str2 = map.remove(2);    
                System.out.println(str2); //Thor  
                
                //通过key 获取 value      
                String str3 = map.get(3);      
                System.out.println(str3);  //super man   
                
                //判断某个key,value是否存在  
                System.out.println(map.containsKey(3)); 
                System.out.println(map.containsValue("Thor")); 
                
                //遍历集合      
                Set<Integer> set = map.keySet(); //将map集合所有key取出放在set集合中  
                Iterator<Integer> it = set.iterator();  //使用迭代器    
                while (it.hasNext()){        
                    System.out.println(map.get(it.next()));   
                }   
                
                for (Integer key:set) {  //使用foreach  
                    System.out.println(map.get(key));   
                } 
                
                Set<Map.Entry<Integer,String>> set = map.entrySet(); //使用EntrySet获取Entry集合set       
                //...  
            }
        }
    
  • Hashtable

    相比于HashMap,单线程,线程安全。不能key和value都不能为null。

多线程

1.创建多线程的方法
  • 继承Thread类,重写run方法

    public class a1_MyThread extends Thread{ 
        @Override   
        public void run() { 
            
            //获取并输出线程名称  
            System.out.println(getName());  
            
            //修改线程名称    
            Thread.currentThread().setName("小强");   
            System.out.println(getName());    
            
            //让线程休眠   
            try {      
                Thread.sleep(3000); 
            } catch (InterruptedException e) {      
                e.printStackTrace();   
            }  
        }
    }
    
    public class a2_GetMyThread {
        public static void main(String[] args) {
            a1_MyThread mt = new a1_MyThread();
            mt.start();
    
           System.out.println(Thread.currentThread().getName());//获取当前线程名称
        }
    }
    
    
  • 实现Runnable接口,重写run方法

    public class a3_RnunableImpl implements Runnable{  
        @Override  
        public void run() {     
            for (int i = 0; i < 20; i++) {      
                System.out.println(Thread.currentThread().getName()+i); 
            }   
        }
    }
    
    public class a4_GetRunnableImpl {
        public static void main(String[] args) {
    
            a3_RnunableImpl impl = new a3_RnunableImpl();
            Thread t = new Thread(impl);
            t.start();
    
            for (int i = 0; i < 20; i++) {
                System.out.println(Thread.currentThread().getName()+i);
            }
        }
    }
    
  • 两者的区别

    或者避免了单继承的局限性,分离了设置线程任务和开启新线程,提高了程序的扩展性

2.线程安全问题
  • 同步代码块

    public class a5_ThreadSafety implements Runnable{   
        private int ticket = 100; 
        
        //创建一个锁对象  
        Object obj = new Object();
        
        @Override  
        public void run() {   
            while (true) {    
                //同步代码块  
                synchronized(obj){      
                    try {         
                        Thread.sleep(10);//提高发生问题的概率   
                    } catch (InterruptedException e) { 
                        e.printStackTrace();      
                    }              
                    if (ticket > 0) {   
                        System.out.println(Thread.currentThread().getName() + " ---- > " + ticket);      
                        ticket--;      
                    }else{      
                        break;    
                    }      
                }   
            }  
        }  
        
        public static void main(String[] args) {  
            a5_ThreadSafety impl = new a5_ThreadSafety();    
            new Thread(impl).start();  
            new Thread(impl).start();     
            new Thread(impl).start();  
        }
    }
    

    需要频繁的判断,获取,释放锁。

  • 同步方法

    @Override
    public void run() { 
        payTicket();
    }
    public synchronized void payTicket(){ 
        while (true) {         
            try {       
                Thread.sleep(10);//提高发生问题的概率     
            } catch (InterruptedException e) { 
                e.printStackTrace();     
            }         
            if (ticket > 0) {   
                System.out.println(Thread.currentThread().getName() + " ---- > " + ticket);          
                ticket--;    
            }else{       
                break;   
            } 
        }
    }
    
  • Lock锁

    //创建ReentrantLock对象
    Lock l = new ReentrantLock();
    
    @Override
    public void run() {  
        while (true) {      
            l.lock();//上锁    
            try {         
                Thread.sleep(10);//提高发生问题的概率    
                if (ticket > 0) {  
                    System.out.println(Thread.currentThread().getName() + " ---- > " + ticket);     
                    ticket--;   
                }else{            
                    break;  
                }     
            } catch (InterruptedException e) {       
                e.printStackTrace(); 
            }finally {        
                l.unlock();//解锁,写在finally中,无论是否异常,锁都会释放     
            }   
        } 
    }
    
3.线程状态

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HNg7lrtl-1583461276914)(D:\学习资源\JPG\snipaste\Snipaste_2019-07-23_09-54-24.png)]

4.Lambda表达式

格式:( 参数列表)->{

​ 重写的方法体;

}

public static void main(String[] args) {
    new Thread(()->{     
        System.out.println(Thread.currentThread().getName()); 
    }).start();
}

File类与IO流

1.File

关键单词:file,directory,path

常量:

System.out.println(File.pathSeparator); //;

System.out.println(File.separator); // \

  • 构造方法

    File(File parent, String child)从父抽象路径名和子路径名字符串创建新的File`实例

    File(String pathname)通过将给定的路径名字符串转换为抽象路径名来创建新的File`实例。

    File(String parent, String child)从父路径名字符串和子路径名字符串创建新的File`实例。

    File(URI uri)通过将给定的file:URI转换为抽象路径名来创建新的File`实例

常用方法:详见API文档

2.io流

网络编程

    1. 软件结构:C/S,B/S
    2. 协议:网络传输规则,TCP ,
    3. IP地址:电脑的网络位置,相当于电话号码
    4. 端口:网络软件的标记,门牌号

JDK8新特性

1.函数式接口

有且只有一个抽象方法的接口,使用@FuntionalInterface注解

2.stream流

得益于lambda表达式,可以使用stream流优雅的处理集合对象

public static void main(String[] args) {  
    ArrayList<String> list = new ArrayList<>();    
    Collections.addAll(list,"werwe","dsad","saasda","sd","fass","dasf","dsd");    
    list.stream()
        .filter((name)->name.startsWith("d"))
        .filter((name)->name.length() > 3)
        .forEach((name)->System.out.println(name)); //dsad,dasf
}

**注:**许多常用方法,请参见API

3.方法引用

反射

反射:框架设计的灵魂

  • 框架:半成品软件,可以在框架的基础上进行软件开发,简化编码
  • 反射:将类的各个组成部分分装为其他对象,这就是反射机制

好处:

  1. 可以在程序运行过程操作这些对象。
  2. 可以解耦,提高程序的可扩展性。

你可能感兴趣的:(学习笔记)