Java基础学习笔记(一)_Java核心技术(基础)

本篇文章的学习资源来自Java入门视频教程:Java核心技术_华东师范大学_中国大学MOOC(慕课)
本篇文章的学习笔记即是对Java核心技术课程的总结,也是对自己学习的总结

第一章:Java概述
Java简介
  • Java1995年诞生
  • 出身于SUN公司,现被Oracle(甲骨文)收购
  • 目标:一次编写,到处运行。兼容各种不同体系结构的CPU、操作系统
  • Java是一种面向对象的语言
    • 将源代码编译成字节码(bytecode,中间态)
    • 然后依赖各种不同平台上的虚拟机来解释执行字节码
    • 实现"一次编写,到处运行"的跨平台特性
Java三大分支:

Java SE(Standard Edition)面向PC级应用开发

Java EE(Enterprise Edition)面向企业级应用开发,学习EE主要是学习框架SSM,spring Boot

Java ME(Micro Edition)面向嵌入式应用开发

Java环境搭建

Java技术体系

Java技术体系至少包含四个部分:

1、Java程序设计语言

2、各种平台上的Java虚拟机(JVM)

3、Java API类库

4、一系列辅助工具,如javac

JDK>JRE>JVM

1+2+3+4=JDK;2+3=JRE;

注:IDE是不会编译和运行程序的。程序的编译与运行需要JDK的支持。

​ .NET的编译和运行(MSBuild编译器)集成在VS中,而Java开发仅有IDE是不行的,还需要依赖JDK

Java和.NET的类比:

Java包括:1、Java语言;2、JVM;3、Java API;4、JDK

.NET包括:1、多种程序设计语言(C#、VB.NET、C++.NET、J#);2、CLR;3、.NET基础类库

.NET中MSBuilder类似JDK,集成在VS中。CLR类似JVM

Java从编写到运行

编写:利用IDE等完成代码文件(.java)编写

编译:利用JDK中javac.exe将代码(.java)编译成字节码文件(.class)

运行:java.exe读入并解释字 节码文件(.class),最终在JVM上运行

image-20200709154907680

image-20200710155705506

第二章:Java类基础知识
一、java类结构

Java文件必须以.java作为扩展名

一个Java文件只能有一个public class

public class的名字必须与文件名字完全一致

多个class可以写在一个.java文件中,但是最多只能有一个类是public class,并且public class类的名字必须和.java的文件名相同

System.out.print输出
System.out.println输出换行

类是Java中最基本的逻辑单位

Java所有的内容都是需要放在类的范围中

内容不允许游离在类以外

换言之,Java项目就是由一个个类组成的

类的构成:

成员变量

成员函数

main函数

main函数是一个Java文件的总入口

main函数不属于成员函数

严格来说,main函数不属于这个类的所拥有函数,只是“寄存”在这个类中

二、基本类型和运算符

基本类型(8个):boolean、byte、short、int、long、float、double、char

注:

​ byte:-128~127,

​ short大小2字节,

​ int大小4字节,大约10位数,首位为2

​ long在数字末尾要加L

​ float在数字末尾要加f

​ double在数字末尾可以省略d

​ char是一个单一的16位Unicode字符

注:

八种基本类型的内部属性默认值分别为:

bool false

byte 0 short 0 int 0 long 0L

float 0.0f double 0.0d

char ‘\u0000’(空格)

算数运算符

  • ~ >>右移 a>>1 //右移,除以2
  • ~<<左移 b<<2 //左移,乘以4
三、选择和循环结构
四、自定义函数
第三章:面向对象和类

注:函数内的局部变量,编译器不会给默认值,需要初始化后才可以使用;类的成员变量,编译器会给默认值,可以直接使用

原因:类的构造函数

构造函数的有参构造函数调用无参构造函数:

class Test {
    public Test() {
        System.out.println("1");
    }
    public Test(int a) {
        this();
        System.out.println("2");
    }
}
第四章:继承、接口和抽象类
继承

关键字:extends

单根继承原则:每个类都只能继承一个类。如果不写extends,Java类都默认继承自java.lang.Object类

注:每个子类的构造函数的第一句话,都默认调用父类的无参构造函数super(),除非子类的构造函数第一句话是super,而且super语句必须放在第一条,不会出现连续两条super语句。

抽象类和接口

抽象类:abstract,抽象类不能new

子类可以继承于抽象类,但是一定要实现父类们所有abstract的方法。如果不能完全实现,那么子类也必须被定义为抽象类。

接口:interface 关键字:implements

如果类的所有方法都没有实现,那么这个类就算是接口类

类只可以继承(extends)一个类,但可以实现(implements)多个接口,继承和实现可以同时

interface是一种特殊的类

接口可以继承多个接口,没有实现的方法将会叠加

类实现接口,必须实现所有未实现的方法。如果没有全部实现,那么只能成为一个抽象类。

接口里可以定义变量,但是一般是常量。

注:extends必须写在implements前面

抽象类和接口相同点:两者都不能被实例化,不能new操作

​ 不同点:

抽象类(abstract)接口(Interface)
可以有部分方法实现所有方法都不能实现
一个类只能继承(extends)一个(抽象)类一个类可以实现(implements)多个接口
接口可以继承(extends)多个接口
抽象类有构造函数接口没有构造函数
抽象类有main函数接口没有main函数
抽象类可以有private/protected接口方法都是public
转型、多态和契约设计
  • 变量支持互相转化,比如int a=(int)3.5;

  • 类型可以相互转型,但是只限于有继承关系的类

    子类可以转换成父类,而父类不可以转为子类

    子类继承父类所有的财产,子类可以变成父类(从大到小,即向上转型);从父类直接变成子类(从小变大,即向下转型)则不允许。

    父类转为子类有一种情况例外,就是这个父类本身就是从子类转化过来的。

第五章:static、final和常量设计
1、static

static方法

  • 在静态方法中,只能使用静态变量,不能使用非静态变量;
  • 静态方法禁止引用非静态方法

static块:

  • static块只在类第一次被加载时调用,只运行一次
  • 执行顺序:static块>匿名块>构造函数

注:不建议编写块代码,因为块代码会给程序带来混淆。建议将块代码封装成函数再调用

2、单例模式
  • 单例模式,又名单态模式,Singleton。
  • 限定某一个类在整个程序运行过程中,只能保留一个实例对象在内存空间。
  • 内存空间中,一个类只有一个对象存在,这就是单例模式
  • 创建型设计模式

单例模式:保证一个类有且只有一个对象

采用static来共享对象实例

采用private构造函数,防止外界new操作

3、final
  • final关键字可以用来修饰类、方法、字段
  • final的类,不能被继承
  • 父类中如果有final的方法,子类中不能改写此方法
  • final的变量,不能再次赋值
    • 如果是基本型别的变量,不能·修改其值
    • 如果是对象实例,不能修改其指针,但是可以修改对象内部的值

final类:没有子类继承

final方法:不能被子类改写

final字段:基本类型不能修改值,对象类型不能修改指针

4、常量设计与常量池

常量:

  • 不能修改,final(java没有const关键字,所以相当于在final充到const的位置)
  • 不会修改/只读/只要一份,static
  • 方便访问public

​ 所以:java中的常量:public static final

  • 一种特殊的常量:接口内定义的变量默认是常量

常量池

  • Java为很多基本类型的包装类/字符串都建立常量池
  • 常量池:相同的值只存储一份,节省内存,共享访问
  • 基本类型的包装类:
    • Boolean,Byte,Short,Integer,Long,Character,Float,Double
    • Boolean:true,false
    • Character:0-127
    • Byte,Short,Int,Long:-128-127
    • Float,Double:没有缓存(常量池)
  • Java为常量字符串都建立常量池缓存机制
  • 在常量池中的这些字符串不会被垃圾收集器回收

常量池的作用:

  1. 节约内存
  2. 共享访问

基本类型的包装类和字符串有两种创建方式:

  • 常量式(字面式)赋值创建,放在栈内存(将被常量化)
    • Integer a = 10;
    • String b = “abc”;
  • new对象进行创建,放在堆内存(不会常量化)
    • Integer c = new Integer(10);
    • String d = new String(“abc”);
  • 这两种创建方式导致创建的对象存放的位置不同
    • 栈内存读取速度快但容量小
    • 堆内存读取速度慢但容量大

基本类型:

int i1 = 10;
Integer i2 = 10;//自动装箱
System.out.println(i1 == i2);//true
//自动拆箱  基本类型和包装类进行比较,包装类自动拆箱
Integer i3 = new Integer(10);
System.out.println(i1 == i3);//true
//自动拆箱  基本类型和包装类进行比较,包装类自动拆箱
System.out.println(i2 == i3);//false
//两个对象比较,比较其地址
//i2是常量,放在栈内存常量池中,i3是new出的对象,放在堆内存中
Integer i4 = new Integer(5);
Integer i5 = new Integer(5);
System.out.println(i1 == (i4 + i5));//true
System.out.println(i2 == (i4 + i5));//true
System.out.println(i3 == (i4 + i5));//true
//i4+i5操作会使得i4、i5自动拆箱为基本类型并运算得到10
//基础类型10和对象比较,将会使对象自动拆箱,做基本类型比较

字符串

String s0="abcdef";
String s1="abc";
String s2="abc";
String s3=new String("abc");
String s4=new String("abc");
System.out.println(s1==s2);//true   常量池
System.out.println(s1==s3);//false  一个栈内存,一个堆内存
System.out.println(s3==s4);//false  两个都是堆内存

String s5=s1+"def";//涉及到变量,故编译器不优化
String s6="abc"+"def";//都是常量 编译器会自动优化成abcdef
String s7="abc"+new String("def");//涉及到new对象,编译器不优化
System.out.println(s5==s6);//false
System.out.println(s5==s7);//false
System.out.println(s6==s7);//false
System.out.println(s0==s6);//true
总结:
  • Java中的常量:static和final
  • Java接口中的变量都是常量
  • 对象生成有两种:常量赋值(栈内存)和new创建(堆内存)
  • Java为Boolean,Byte,Character,Short,Int,Long,String的常量赋值建立常量池,没有包括Float和Double
  • Java编译器会优化已经确定的变量
5、不可变对象和字符串

**不可变对象:**值对象不再修改,而指针的指向可以修改

  • 一旦创建,这个对象(状态/值)不能被更改了
  • 其内在的成员变量的值就不能修改了
  • 包括八个基本型别的包装类,String,BigInteger和BigDecimal等

可变对象:普通对象,

不可变对象优点:

  • 只读,线程安全
  • 并发读,提高性能
  • 可以重复使用

缺点:

  • 制造垃圾,浪费空间
Java字符串
  • 字符串是Java使用最多的类,是一种典型的不可变对象
  • String定义有2种:
    • String a = “abc”;//常量赋值,栈分配内存
    • String b = new String(“abc”);//new对象,堆分配内存
  • 由于String不可修改,效率差
  • StringBuffer/StringBuilder的对象都是可变对象
  • StringBuffer(同步,线程安全,修改快速);StringBuilder(不同步,线程不安全,修改更快)
  • 在程序运行当中,如果需要大量的字符串加法操作,建议使用StringBuffer或StringBuilder
第六章:package、import和classpath
package、import
  • package(包),和C#中的导入引用,nameplace类似
  • import(引用),和C#中的using类似

注:可以用*来引入一个目录下的所有类,但仅限于该目录下的,不包含其下的子文件夹下的目录

并且,import尽量精确,不推荐使用*,以免新增的同名程序会使得老程序报错

jar文件导出和导入
  • .java文件最终会被编译成.class文件(二进制),并被分发到其他机器上使用
  • jar文件,一种扩展名为jar的文件,是Java所特有的一种文件格式,用于可执行程序文件的传播
  • jar文件实际上是一组class文件的压缩包
  • 项目引入一个jar文件,就可以使用jar文件中的所有类(.class文件),无需类的源码(.java文件)
  • jar文件与C#的dll文件类似
Java访问方法

image-20201127204202971

类的权限:

  1. public
  2. default

内部类的权限:

  1. public
  2. protected
  3. default
  4. private
第七章 Java常用类
1、Java类库概述

Java类库主要包含Java、javac、org三个

  • java.io.* 数据流、对象序列、文件系统的输入输出
  • java.lang.* Java编程语言的基础类库
  • java.math.* 基本数学函数
  • java.text.* 格式化文本
  • java.time 日期、时间类
  • java.util.* 包括集合类、时间处理模式、日期时间工具等各类常用工具包
2、数字相关类

Java数字类

  • 整数 Short,Int,Long
  • 浮点数 Float,Double
  • 大数类 BigInteger(大数类),BigDecimal(大浮点数)
  • 随机数Random
  • 工具类Math

Random随机数用法

  • nextInt()返回一个随机int
  • nextInt(int a)返回一个[0,a)之间的随机int
  • nextDouble()返回一个[0.0,1.0]之间double
  • ints方法批量返回随机数数组
  • Math.random()返回一个[0.0,1.0]之间double

Math函数用法

  • 绝对值abs
  • 对数log
  • 比较函数max\min
  • 幂函数pow
  • 四舍五入函数round
  • 向下取整floor
  • 向上取整ceil
3、字符串相关类
  • 是一个不可变对象,加减操作性能较差
  • 常用方法:
    • charAt() 返回第x个元素
    • indexOf(d) 返回第一个d的位置
    • concat() 连接一个新字符串并返回,但原字符串不变化
    • contain()包含操作
    • endsWith()是否以…结尾
    • equals()判断是否等于 equalsIgnoreCase()忽略大小写
    • length()返回长度
    • trim()去除前后空格
    • split(d)将字符串按照d分割成数组
    • substring(num1,num2)截取第num1到num2的字符,原字符串不变

可变字符串

  • StringBuffer(字符串加减,同步,性能好)
  • StringBuilder(字符串加减,不同步,性能更好)
    • append/insert/delete/replace/substring
    • length字符串实际大小,capacity字符串占用空间大小
4、时间相关类
  1. java.util.Date(基本废弃,Deprecated)

  2. java.sql.Date(和数据库对应的时间类)

  3. Calendar是目前程序中最常用的,但是是抽象类

    1. Calendar gc=Calendar.getInstance();
      Calendar gc=new GregorianCalendar();
      
    • get(Field) 来获取时间中每个属性的值。注意,月份0-11
    • getTime() 返回相应的Date对象
    • getTimeInMillis(),返回自1970.1.1以来的毫秒数
Calendar instance = Calendar.getInstance();
int year = instance.get(Calendar.YEAR);
int month = instance.get(Calendar.MONTH) + 1;
int day = instance.get(Calendar.DAY_OF_MONTH);
int hour = instance.get(Calendar.HOUR);
int hour1 = instance.get(Calendar.HOUR_OF_DAY);
int minute = instance.get(Calendar.MINUTE);
int second = instance.get(Calendar.SECOND);
int weekday = instance.get(Calendar.DAY_OF_WEEK);

4、java.time

  • LocalDate:日期类
  • LocalTime:时间类
  • LocalDateTime:LocalDate+LocalTime
  • Instant:时间戳
LocalDate today=LocalDate.now();
//根据指定时间创建LocalDate
LocalDate firstDay=LocalDate.of(2001, Month.JANUARY,1);
5、格式化相关类

java.text.Format包

  • NumberFormat:数字格式化,抽象类

    • DecimalFormat
  • MessageFormat:字符串格式化

    • MessageFormat.format(mess,array);
      String world = MessageFormat.format("hello{0}", "world");
      
  • DateFormat:日期/时间格式化,抽象类

    • SimpleDateFormat 工厂模式
      • parse:将字符串格式化为时间对象
      • format:将时间对象格式化为字符串
第八章:Java异常处理与分类
1、Java异常分类

分类一:

image-20201129102233116

  • Throwable:所有错误的祖先
  • Error:系统内部错误或者资源耗尽。不管
  • Exception:程序有关的异常。重点关注。
    • RuntimeException:程序自身的错误
      • 5/0,空指针,数组越界…
    • 非RuntimeException:外界相关的错误
      • 打开一个不存在的文件
      • 加载一个不存在的类…

分类2:

  • Unchecked Exception:(编译器不会辅助检查的,需要程序员自己管的)异常,包括Error子类和RuntimeException子类。以发生前预防为主
  • Checked Exception:(编译器会辅助检查的)异常,非RuntimeException子类。以发生后处理为主
2、Java异常处理

try-catch-finally

try-catch-finally快捷键:

​ 选中想被 try / catch / finally 包围的语句,同时按下 Ctrl + Alt + T

注:若catch内部再次发生异常,也不影响finally的正常运行。异常发生时,先执行finally,再程序报错

  • catch块可以有多个,但一个异常只能进入一个catch块
  • catch块的异常匹配从上到下
  • 所以一般是将小的异常写在前面,一些大(宽泛)的异常写在后面

throw(手动抛出异常)

  • 调用带有throws异常的方法,要么处理这些异常,或者再次向外throws,直到main函数为止

try块与throw的异同:

try块与throw的目的相同,用途不同。

  • 都是捕获异常。try块是捕获异常并抛出异常,throw向外抛异常
  • 底层用throw抛出异常,经过多层处理,在顶层try捕获异常,并作出相应处理
3、自定义异常
  • 自定义异常,需要继承Exception类或其子类

    • 继承自Exception,就变成Checked Exception
    • 继承自RuntimeException,就变成Unchecked Exception
  • 自定义重点在构造函数

    • 调用父类Exception的message构造函数
    • 可以自定义自己的成员变量
  • 在程序中采用throw主动抛出异常

  • 在方法内部程序中,抛出异常采用throw关键字;在方法头部声明中,声明异常采用throws关键字

自定义异常类:

public class MyExceptionTest extends Exception {
    private String returnCode;//异常对应的返回码
    private String returnMsg;//异常对应的描述信息

    public MyExceptionTest() {
        super();
    }

    public MyExceptionTest(String returnMsg) {
        super(returnMsg);
        this.returnMsg = returnMsg;
    }

    public MyExceptionTest(String returnCode, String returnMsg) {
        super();
        this.returnCode = returnCode;
        this.returnMsg = returnMsg;
    }

    public String getReturnCode(){
        return returnCode;
    }

    public String getReturnMsg(){
        return returnMsg;
    }
}
public static void main(String[] args) {
    try {
        MyExceptionTestTest.TestException();
    } catch (MyExceptionTest e){
        e.printStackTrace();
        System.out.println("e.getReturnCode() = " + e.getReturnCode());
        System.out.println("e.getReturnMsg() = " + e.getReturnMsg());
    }
}

//这是一个测试自定义异常的方法
public static void TestException() throws MyExceptionTest{
    throw new MyExceptionTest("10001","The reason of myException");
}
public static void main(String[] args) throws MyExceptionTest {
    int a = 9 / 3;
    if (a == 3) {
        throw new MyExceptionTest("1001", "a=3");
    }
}
第九章:Java数据结构
1、数组
  • 数组是一个存放多个数据的容器
    • 数据是同一种类型
    • 所有的数据是线性规则排列
    • 可通过位置索引来快速定位访问数据
    • 需明确容器的长度

Java数组的定义和初始化

int a[];
int[] b;//还没有new操作,实际上是null,也不知道内存位置
int[] c = new int[2];//c有两个元素,都是0
int[] d = new int[]{0,2,4};

数组初始化两种方式:

  1. 动态初始化(指定长度),在创建数组时,直接指定数组中元素的个数

    String[] arr = new String[2];
    
  2. 静态初始化(指定内容),在创建数组时,不指定数组长度,赋值内容,由编译器自动判断数组长度

    int[] arr1 = new int[]{5, 15, 25};
    
    • 静态初始化,格式可以省略一下

      int[] arr2 = {5, 15, 25};
      
2、JCF(容器):Java Collection Framework
  • 容器:能够存放数据的空间结构

    • 数组/多维数组,只能线性存放
    • 列表/散列集/树/…
  • 容器框架:为表示和操作容器而规定的一种标准体系结构

    • 对外的接口:容器中所能存放的抽象数据类型
    • 接口的实现:可复用的数据结构
    • 算法:对数据的查找和排序
  • 容器框架优点:提高数据存储效率,避免程序员重复劳动

  • JCF的集合接口是Collection

    • add,contains,remove,size

    • iterator(迭代器接口)

      迭代:迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。

      • hasNext 判断是否有下一个元素
      • next 获取下一个元素
      • remove 移除某一个元素
  • JCF主要的数据结构实现类:

    • 列表(ArrayList,LinkedList,Vector)
    • 集合/散列集(Set,HashSet,TreeSet,LinkedHashSet)
    • 映射(Map,HashMap,TreeMap,LinkedHashMap)
  • JCF主要的算法类(工具类)

    • Arrays:对数组进行查找和排序等操作
    • Collections:对Collection及其子类进行排序和查找操作
3、列表List
  • 有序的Collection

  • 允许重复元素 {1,2,4,{5,2},1,3}

  • List主要实现

    • ArrayList(非同步的)
    • LinkedList(非同步)
    • Vector(同步)
  • ArrayList:

    • 缺点:以数组实现的列表,不支持同步
    • 利用索引位置可以快速定位访问
    • 不适合指定位置的插入、删除操作(会导致后面数据的大规模移动)
    • 适合变动不大,主要用于查询的数据
    • 和数组相比,其容量是可动态调整的
      • ArrayList在元素填满容器时会自动扩充容器大小的50%
    • ArrayList遍历方式
      1. Iterator遍历(最慢)
      2. 索引位置遍历
      3. foreach遍历
    /**
     * Iterator遍历ArrayList的方法
     */
    private static void testArrayListIterator(ArrayList<Integer> a1) {
        long startTime = System.nanoTime();
        System.out.println("Iterator遍历");
        Iterator<Integer> iter1 = a1.iterator();
        while (iter1.hasNext()) {
            iter1.next();
        }
        long endTime = System.nanoTime();
        long duration = endTime - startTime;
        System.out.println("duration = " + duration);
    }
    /**
     * 索引位置遍历ArrayList
     */
    private static void testIndexArrayList(ArrayList<Integer> a1) {
        long startTime = System.nanoTime();
        System.out.println("Index遍历");
        for (int i = 0; i < a1.size(); i++) {
            a1.get(i);
        }
        long endTime = System.nanoTime();
        long duration = endTime - startTime;
        System.out.println("duration = " + duration);
    };
    /**
     * foreach位置遍历ArrayList
     */
    private static void testForeachArrayList(ArrayList<Integer> a1) {
        long startTime = System.nanoTime();
        System.out.println("Foreach遍历");
        for (Integer item : a1) {
            ;
        }
        long endTime = System.nanoTime();
        long duration = endTime - startTime;
        System.out.println("duration = " + duration);
    }
    
  • LinkedList

    • 以双向链表实现的列表,不支持同步
    • 可被当做堆栈、队列和双端队列进行操作
    • 顺序访问高效,随机访问较差,中间插入和删除高效
    • 适合于经常变化的数据
    • LinkList遍历方式
      1. Iterator遍历
      2. 索引位置遍历(最慢)
      3. foreach遍历

ArrayList与LinkedList比较:ArrayList适用于较多查询的(静态数据),LinkedList适用于频繁增删的数据

  • Vector(同步)
    • 和ArrayList类似,可变数组实现的列表
    • Vector同步,适合在多线程下使用
    • 官方文档建议:在非同步情况下,优先采用ArrayList
    • 同步采用Vector,非同步情况下,根据数据操作特点选取ArrayList/LinkedList
4、集合Set

集合Set:

  • 确定性:对任意对象都能判定其是否属于某一个集合
  • 互异性:集合内每个元素都是不相同的,注意是内容互异
  • 无序性:集合内的顺序无关

Java中的集合接口Set

  • HashSet(基于散列函数的集合,无序,不支持同步)
  • TreeSet(基于树结构的集合,可排序的,不支持同步)
  • LinkedHashSet(基于散列函数和双向链表的集合,可排序的,不支持同步)

HashSet:

  • 基于HashMap实现的,可以容纳null元素,不支持同步

    • 同步操作:Set s = Collections.synchronizedSet(new HashSet<>());
      
  • add/clear/contains/remove/size

  • retainAll计算两个集合的交集

  • 遍历方法

    • Iterator迭代器
    • foreach(快)

LinkedHashSet:

  • 继承HashSet,也是基于HashMap实现的,可以容纳null元素,有序的,不支持同步

    • 同步操作:Set s = Collections.synchronizedSet(new LinkedHashSet<>());
      
  • 方法与HashSet基本一致。HashSet无序,而LinkedHashSet有序

  • 通过一个双向链表维护插入顺序

TreeSet:

  • 基于TreeMap实现,不可以容纳null元素,不支持同步

    • 同步操作:SortedSet s = Collections.synchronizedSortedSet(new TreeSet<>());
      
  • add/clear/contains/remove/size

  • TreeSet是按照所存储对象大小升序输出的

  • 根据compareTo方法或指定Comparator排序

HashSet/LinkedHashSet/TreeSet三者比较

  • HashSet/LinkedHashSet/TreeSet三者的元素都只能是对象

  • HashSet是无序输出的;LinkedHashSet是按照插入顺序进行遍历输出的;TreeSet是按照所存储对象大小升序输出的

  • 判定元素重复原则:

    • HashSet和LinkedHashSet判定元素重复:

      • 判定两个元素的hashCode返回值是否相同,若不同,则返回false;
      • 若hashCode相同,判定equals方法,若不同,返回false;否则返回true
      • hashCode和equals方法是所有类都有的,因为Object类有
    • TreeSet判定元素重复原则:

      • 需要元素继承自Comparable接口

      • 比较两个元素的CompareTo方法

    • 这3个方法三位一体:

      • equals()是相同的;
      • hashCode()是相同的;
      • toString()也应该是相同的
    • Java的四个重要接口

      • Comparable:可比较的
      • Clonable:可克隆的
      • Runnable:可线程化的
      • Serializable:可序列化的
5、映射Map

Map映射

  • 数学定义:两个集合之间的元素对应关系
  • 一个输出对应到一个输出
  • {1,张三},{Key,Value},键值对,K-V对

Java中Map

  • HashTable(同步,慢,数据量小);
  • HashMap(不支持同步,快,数据量大);
  • Properties(同步,文件形式,数据量小)

HashTable

  • K-V对,K和V都不允许为null
  • 同步,多线程安全
  • 无序的
  • 适合小数据量
  • clear/contains/containsValue/containsKey/get/put/remove/size
    • contains等同于containsValue
    • get根据key获取相应的值,返回Value
    • put增加新的K-V对
    • remove删除某一个K-V对
  • 遍历方法
    1. 根据Entry迭代器遍历
    2. 根据Key的Iterator遍历
    3. 根据Key的Enumeration遍历(老接口,只读)
public static void main(String[] args) {
    Hashtable<Integer, String> integerStringHashtable = new Hashtable<>();
    for (int i = 0; i < 10000; i++) {
        integerStringHashtable.put(i, "aaa");
    }
    traverseByEnter(integerStringHashtable);
    traverseByKeyIterator(integerStringHashtable);
    traverseByKeyEnumeration(integerStringHashtable);
}
private static void traverseByEnter(Hashtable<Integer, String> ht) {
    long startTime = System.nanoTime();
    System.out.println("Entry迭代器遍历");
    Integer key;
    String value;
    Iterator<Map.Entry<Integer, String>> iter = ht.entrySet().iterator();
    while (iter.hasNext()) {
        Map.Entry<Integer, String> entry = iter.next();
        //获取key
        key = entry.getKey();
        //获取value
        value = entry.getValue();
    }
    long endTime = System.nanoTime();
    long duration = endTime - startTime;
    System.out.println("duration = " + duration);
}
private static void traverseByKeyIterator(Hashtable<Integer, String> ht) {
    long startTime = System.nanoTime();
    System.out.println("KeySet迭代器遍历");
    Integer key;
    String value;
    Iterator<Integer> iter = ht.keySet().iterator();
    while (iter.hasNext()) {
        key = iter.next();
        //获取value
        value = ht.get(key);
    }
    long endTime = System.nanoTime();
    long duration = endTime - startTime;
    System.out.println("duration = " + duration);
}
private static void traverseByKeyEnumeration(Hashtable<Integer, String> ht) {
    long startTime = System.nanoTime();
    System.out.println("KeyEnumeration迭代器遍历");
    Integer key;
    String value;
    Enumeration<Integer> keys = ht.keys();
    while (keys.hasMoreElements()) {
        key = keys.nextElement();
        //获取value
        value = ht.get(key);
    }
    long endTime = System.nanoTime();
    long duration = endTime - startTime;
    System.out.println("duration = " + duration);
}

HashMap:

  • K-V对,K和V都允许为null
  • 不同步,多线程,不安全
  • 无序的
  • 主要方法与HashTable类似
  • 遍历方法
    1. 根据Entry迭代器遍历
    2. 根据Key的Iterator遍历

LinkedHashMap

  • 基于双向链表的维持插入顺序的HashMap

TreeMap

  • 基于红黑树的Map,可以根据key的自然排序或者compareTo方法进行排序输出

Properties

  • 继承于HashTable
  • 可以将K-V对保存在文件中
  • 适用于数据量小的配置文件
  • 继承自HashTable的方法:clear/contains/containsValue/containsKey/get/put/remove/size
  • 从文件加载的load方法,写入到文件中的store方法
  • 获取属性getProperty,设置属性setProperty

总结:

  • HashMap是最常用的映射结构
  • 如需排序,考虑LinkedHashMap和TreeMap
  • 如需将K-V存储为文件,可采用Properties
6、工具类

JCF中工具类

  • 不存储数据,而是在数据容器上,实现高效操作
    • 排序
    • 搜索
  • Arrays类
  • Collections类

Arrays:处理对象是数组

  • 排序:对数组排序,sort/parallelSort
  • 查找:从数组中查找一个元素,binarySearch
  • 批量拷贝:从源数组批量复制元素到目标数组,copyOf
  • 批量赋值:对数组进行批量赋值,fill
  • 等价性比较:判定两个数组内容是否相同,equals

Collections:处理的对象是Collection及其子类

  • 排序:对List进行排序,sort
  • 搜索,从List中搜索元素,binarySearch
  • 批量赋值:对List批量赋值,fill
  • 最大最小:查找集合中最大/最小值,max,min
  • 反序:将List反序排列,reverse

对象比较

  • 对象实现Comparable接口(需要修改对象类)
    • compareTo方法
      • >返回1,==返回0,<返回-1
    • Arrays和Collections在进行对象sort时,自动调用该方法
  • 新建Comparator(适合于对象类不可更改的情况)
    • compare方法
      • >返回1,==返回0,<返回-1
    • Comparator比较器将作为参数提交给工具类的sort方法
第十章:Java文件读写
1、文件系统及Java基本操作

Java文件类File

  • java.io.File
  • 常用方法:createNewFile,delete,exists,getAbsolutePath,getName,getParent,getPath,isDirecotry,isFile,length,listFiles,mkdir,mkdirs
    • createNewFile创建新文件(非目录)
    • mkdir:创建一级(一层)目录;mkdirs:创建多级(多层)目录
    • isDirectory是否是目录;isFile是否是目录
    • getName,获取文件名字;getParent获取上一层目录路径;getPath获取文件全路径;length获取文件大小;lastModifiedTime返回文件最后一次修改时间
    • listFiles列出当前目录的所有子文件,但不包括子目录下的文件
  • File不涉及到具体的文件内容,只涉及属性
  • **注:**java中目录和文件都是采用File类

NIO包:是java.io.File的有益补充

  • Path类
  • file的移动(move)、复制、属性访问…
2、Java io包概述
  • Java读写文件,只能以(数据)流的形式进行读写
  • java.io流中包括字节流、字符流、其他流(System)、文件处理
  • java.io包中
    • 节点类:直接对文件进行读写
    • 包装类
      • 转化类:字节/字符/数据类型的转化类
      • 装饰类:装饰节点类
  • 节点类:直接操作文件类
    • InputStream.OutputStream(字节)
      • FileInputStream,FileOutputStream
    • Reader,Writer(字符)
      • FileReader,FileWriter
  • 转换类:字符到字节之间的转化
    • InputStreamReader:文件读取时字节,转换为字符
    • OutputStreamWriter:Java向文件输出时,字符转换为字节
  • 装饰类:装饰节点类
    • DataInputStream,DataOutputStream:封装数据流
    • BufferInputStream,BufferOutputStream:缓存字节流
    • BufferedReader,BufferedWriter:缓存字符流
3、文本文件读写
  • 文件类型
    • 一般文本文件(若干行字符构成的文件),如txt等
    • 一般二进制文件,如数据文件dat,照片文件等
    • 带特殊格式的文本文件,如xml
    • 带特殊格式的二进制文件,如doc,ppt等
  • 文件很大,注定了Java只能以流形式依次处理

写文件:

  • FileOutputStream,OutputStreamWriter,BufferedWriter

    • FileOutputStream:往文件写字节
    • OutputStreamWriter:字节和字符转化
    • BufferWriter:写缓冲区类,加速写操作
      • write
      • newLine //换行
  • try-resource语句,自动关闭资源

  • 关闭最外层的数据流,将会把其上所有的数据流关闭(所以关闭时只需关闭最外层的流)

private static void WriteFile(){
    try (BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("f:/abc.txt")))){
        bw.write("我们是");
        bw.newLine();
        bw.write("abc");
    } catch (Exception exception){
        exception.printStackTrace();
    }
};

注:try后面跟上(),在try结束后会自动释放()内的资源

读文件:

  • 与写文件类似

  • FileInputStream,InputStreamReader,BufferedReader

    • BufferReader:readLine

    • FileInputStream字节类,负责读字节
      InputStreamReader转化类,负责字节到字符转化
      BufferedReader装饰类,负责从缓冲区读入字符
      三者构建关系:
      BufferedReader(InputStreamReader(FileInputStream))
      

总结:

  • 理解节点类、转换类和包装类的联合用法
  • 尽量使用try-resource语句,自动关闭资源
4、二进制文件读写
  • 二进制文件
    • 狭义上说,采用字节编码,而非字符编码的文件
    • 广义上说,一切文件都是二进制文件
    • 用记事本等无法打开或阅读

写文件:

  • FileOutputStream,BufferedOutputStream,DataOutputStream
  • DataOutputStream
    • flush 刷新缓存
    • write/writeBoolean/writeByte/writeChars/writeDouble/writeInt/WriteUTF/…
  • try-resource语句,自动关闭内存
  • 关闭最外层的数据流,将会把其上所有的数据流关闭(所以关闭时只需关闭最外层的流)

读文件:

  • FileInputStream,BufferedInputStream,DataInputStream
  • DataInputStream
    • read/readBoolean/readChar/readDouble/readFloat/readInt/readUTF/…
private static void ReadBinFile() {
    try (DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream("f:/abc.dat")))) {
        String a, b;
        int c, d;
        a = dis.readUTF();
        c = dis.readInt();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
5、Zip文件读写

zip文件操作类:java.util.zip中

  • ZipInputStream,ZipOutputStream压缩文件输入/输出流
  • ZipEntry压缩项

单个/多个压缩

  1. 打开输出zip文件
  2. 添加一个ZipEntry
  3. 打开一个输入文件,读数据,向ZipEntry写数据,关闭输入文件
  4. 重复以上步骤,写入多个文件到zip文件中
  5. 关闭zip文件

单个文件压缩:

public static void main(String[] args) throws IOException {
    File file = new File("F:/abc.txt");//定义要压缩的文件
    File zipFile = new File("F:/abc.zip");//定义压缩文件名称

    InputStream input = new FileInputStream(file);//定义文件的输入流
    ZipOutputStream zipOut = null;//声明压缩流对象
    zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
    zipOut.putNextEntry(new ZipEntry(file.getName()));//设置zipEntry对象
    zipOut.setComment("single file zip");//设置注释
    //压缩过程
    int temp = 0;
    while ((temp = input.read()) != -1) {//读取内容
        zipOut.write(temp);//压缩输出
    }
    input.close();//关闭输入流
    zipOut.close();//关闭输出流
    System.out.println("single file zip done");
}

单个/多个解压:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java基础学习笔记 # 一、Java简介 Java是一种面向对象的编程语言,由Sun Microsystems(现在是Oracle)于1995年首次发布。它具有跨平台的特性,可以在不同的操作系统上运行。Java语言被广泛应用于开发各种类型的应用程序,包括桌面应用、Web应用、移动应用等。 # 二、Java基本语法 ## 1. 变量与数据类型 Java是强类型语言,每个变量必须先声明后使用。Java提供了多种数据类型,包括基本数据类型(整数、浮点数、字符、布尔值)和引用数据类型(类、接口、数组)。 ## 2. 运算符 Java提供了多种运算符,包括算术运算符、关系运算符、逻辑运算符等,用于进行各种数学或逻辑运算。 ## 3. 控制流程 Java提供了多种控制流程语句,包括条件语句(if-else语句、switch语句)、循环语句(for循环、while循环)、跳转语句(break语句、continue语句)等,用于控制程序的执行流程。 ## 4. 方法和类 Java中的方法用于封装一段可重复使用的代码,可以带有参数和返回值。类是Java程序的基本组织单位,包含了属性和方法。可以使用关键字class定义一个类,通过实例化类的对象来调用其方法。 # 三、面向对象编程 Java是一种面向对象的编程语言,面向对象编程的核心概念包括封装、继承和多态。 ## 1. 封装 封装是将数据和行为打包成一个类,通过访问修饰符(public、private等)控制对类的成员的访问权限。 ## 2. 继承 继承允许一个类继承另一个类的属性和方法,并且可以通过重写来修改或扩展继承的方法。 ## 3. 多态 多态允许通过父类类型的引用来引用子类对象,实现对不同子类对象的统一调用。 # 四、异常处理 Java提供了异常处理机制,用于处理程序中的错误情况。异常分为可检查异常(checked exception)和不可检查异常(unchecked exception),可以使用try-catch语句来捕获和处理异常。 # 五、Java标准库 Java标准库提供了大量的类和接口,用于完成各种常见的任务。其中包括输入输出、集合、多线程、网络编程等功能,可以大大简化开发过程。 以上是我学习Java基础笔记总结,希望对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值