Skip to content

java

数据类型

  • 基本数据类型

    • 有八种基本类型:六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型
      • byte、short、int、long, float、double
      • char
      • boolean
      • String (or any object),某认值是null
    • 引用类型
      • 对象、数组都是引用数据类型。
      • 所有引用类型的默认值都是null。
    • 常量
      • 常量在程序运行时是不能被修改的。
      • 使用 final 关键字来修饰常量
      • 虽然常量名也可以用小写,但为了便于识别,通常使用大写字母表示常量。
    • 自动类型转换
      • 整型、实型(常量)、字符型数据可以混合运算。运算中,不同类型的数据先转化为同一类型,然后进行运算。
      • 转换从低级到高级:byte,short,char—> int —> long—> float —> double
      • 转换过程中可能导致溢出或损失精度,例如:int i =128; byte b = (byte)i;
      • short数据类型的位数为16位,就可以自动转换位数为32的int类型,同样float数据类型的位数为32,可以自动转换为64位的double类型;
      • 强制类型转换:格式 (type)value
    • 隐含强制类型转换
      • 整数的默认类型是 int。
      • 小数默认是 double 类型浮点型,在定义 float 类型时必须在数字后面跟上 F 或者 f
  • 数组

    • double[] myList = new double[10];
    • for的两种循环
      • for (int i = 0; i < size; i++) {}
      • for (double element: myList) {}
    • 数组作为函数的参数 printArray(int[] array){}
    • 数组作为函数的返回值 public static int[] reverse(int[] list) {}
    • 多维数组 String[][] str = new String[3][4];
    • java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的;
      • equals 方法比较数组中元素值是否相等
      • 通过 sort 方法,按升序
      • 通过 binarySearch 方法能对排序好的数组进行二分查找法操作
  • 数据结构

    • 列表(Lists)
      • ArrayList
        • 动态数组,可变大小。
        • List<String> arrayList = new ArrayList<>();
        • 该类也是非同步的,在多线程的情况下不要使用;
      • LinkedList
        • 双向链表,元素之间通过指针连接
        • List<Integer> linkedList = new LinkedList<>();
    • 集合(Sets)
      • 用于存储不重复的元素,常见的实现有 HashSet 和 TreeSet。
      • HashSet
        • 无序集合,基于HashMap实现。不保证顺序。
        • Set<String> hashSet = new HashSet<>();
      • TreeSet
        • 是有序集合,底层基于红黑树实现,不允许重复元素。
        • 提供自动排序功能,适用于需要按顺序存储元素的场景。
        • Set<Integer> treeSet = new TreeSet<>();
    • 映射(Maps)
      • 用于存储键值对,常见的实现有 HashMap 和 TreeMap。
      • HashMap
        • 基于哈希表实现的键值对存储结构。无序,不保证顺序。
        • Map<String, Integer> hashMap = new HashMap<>();
      • TreeMap
        • 基于红黑树实现的有序键值对存储结构。
        • 有序,支持按照键的顺序遍历。
    • 栈(Stack)
      • 栈(Stack)是一种线性数据结构,它按照后进先出
      • Stack<Integer> stack = new Stack<>();
    • 队列(Queue)
      • 先进先出(FIFO)原则,常见的实现有 LinkedList 和 PriorityQueue
      • Queue<String> queue = new LinkedList<>();
      • Queue 接口的实现类: LinkedList, PriorityQueue, ArrayDeque。
    • 堆(Heap)
      • 优先队列的基础,可以实现最大堆和最小堆。
      • PriorityQueue<Integer> minHeap = new PriorityQueue<>();
      • PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
    • 树(Trees)
      • Java 提供了 TreeNode 类型,可以用于构建二叉树等数据结构。
    • 图(Graphs)
      • 图的表示通常需要自定义数据结构或使用图库,Java 没有内建的图类。
  • 集合框架

    • java集合框架位于java.util包中, 使用集合框架的时候需要进行导包。
    • 集合框架是一个用来代表和操纵集合的统一架构。所有的集合框架都包含如下内容:
      • 接口:是代表集合的抽象数据类型。例如 Collection、List、Set、Map、Queue 等
      • 实现(类):是集合接口的具体实现,例如:ArrayList、LinkedList、HashSet、HashMap。
      • 算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序;
    • 基本集合(动态数组,链表,树,哈希表)
    • 集合接口的标准实现,诸如: LinkedList, HashSet, 和 TreeSet 等,除此之外你也可以通过这些接口实现自己的集合。
    • 集合框架主要包括两种类型的容器,
      • 一种是集合(Collection),存储一个元素集合,
      • 另一种是图(Map),存储键/值对映射。
    • 除了集合,该框架也定义了几个 Map 接口和类。Map 里存储的是键/值对。尽管 Map 不是集合,但是它们完全整合在集合中。
    • 任何对象加入集合类后,自动转变为Object类型,所以在取出的时候,需要进行强制类型转换。
  • 遍历list和map

    • 遍历 Map
      • 第一种:普遍使用,二次取值 for (String key : map.keySet()) {map.get(key)}
      • 第二种:通过Map.entrySet使用iterator遍历key和value
      • 第三种:推荐,尤其是容量大时 通过Map.entrySet遍历key和value
      • 第四种:通过Map.values()遍历所有的value,但不能遍历key。for (String v : map.values()) {}
    • 三种方法用来遍历ArrayList集合
      • 第一种遍历方法使用 For-Each 遍历 List
      • for(int i=0;i<list.size();i++){}
      • 第三种遍历 使用迭代器进行相关遍历 Iterator<String> ite=list.iterator();
      • while(ite.hasNext()){} // 该方法可以不用担心在遍历的过程中会超出集合的长度
  • 泛型

    • 泛型方法
      • 所有泛型方法声明类型参数部分(由尖括号分隔),泛型参数声明部分在方法返回类型之前( <E>)
      • 泛型方法体的声明和其他方法一样。注意类型参数只能代表引用型类型,不能是原始类型(像 int、double、char 等)。
      • 泛型标记符:
        • E - Element (在集合中使用,因为集合中存放的是元素)
        • T - Type(Java 类)
        • K - Key(键)
        • V - Value(值)
        • N - Number(数值类型)
        • ? - 表示不确定的 java 类型
      • public static < E > void printArray( E[] inputArray ) {} // 方法里面用E表示类型
      • 有界的类型参数(extends)
        • 声明一个有界的类型参数,首先列出类型参数的名称,后跟extends关键字,最后紧跟它的上界。
        • 比如一个操作数字的方法可能只希望接受Number或者Number子类的实例。这就是有界类型参数的目的。
        • public static <T extends Comparable<T>> T maximum(T x, T y, T z) {} // 方法里面用T表示类型
    • 泛型类
      • 泛型类的声明和非泛型类的声明类似,除了在类名后面添加了类型参数声明部分。
      • 和泛型方法一样,泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开
      • public class Box<T> {} // 类里面也是用这个T表示类型
    • 类型通配符
      • 类型通配符一般是使用 ? 代替具体的类型参数。例如 List<?>
      • public static void getData(List<?> data) {}
      • 因为 getData() 方法的参数是 List<?> 类型的,所以 name,age,number 都可以作为这个方法的实参,这就是通配符的作用。
      • public static void getUperNumber(List<? extends Number> data) {} // 限定了参数泛型上限为 Number;
      • 类型通配符下限通过形如 List<? super Number> 来定义,表示类型只能接受 Number 及其上层父类类型,如 Object 类型的实例

常用类

  • Number & Math 类方法
    • Math 的方法都被定义为 static 形式,通过 Math 类可以在主函数中直接调用。
    • toString()
    • parseInt()
    • ceil()
    • floor()
    • round()
    • min()、max()
  • String 类
    • 最简单的方式如下:String str = "Runoob";
    • 也可以用构造函数创建字符串:String str2=new String("Runoob");
    • 字符串长度:int len = site.length();String 方法都是直接在string后面接方法
    • "我的名字是 ".concat("Runoob");也可以使用'+'操作符来连接字符串
    • 创建格式化字符串
      • System.out.printf()
      • String.format(); 两个是样的功能
  • 日期时间
    • import java.util.Date;
    • java.util 包提供了 Date 类来封装当前的日期和时间。 Date 类提供两个构造函数来实例化 Date 对象。
    • Date date = new Date();
    • System.out.println(date.toString());
    • 日期比较
    • 使用 SimpleDateFormat 格式化日期
      • Date dNow = new Date( );
      • SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss");
      • System.out.println("当前时间为: " + ft.format(dNow));

基本语法

  • Java 程序可以认为是一系列对象的集合

  • 基本语法

    • 大小写敏感
    • 类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写
    • 所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。
    • 源文件名必须和类名相同,如果文件名和类名不相同则会导致编译错误;
    • 所有的 Java 程序由 public static void main(String[] args) 方法开始执行。
  • 方法

    • 可变参数 printMax( double... numbers) {}
    • void 关键字,声明和调用一个 void 方法
    • 方法的定义 修饰符 返回值类型 方法名(参数类型 参数名){}, 可以定义全局方法,直接调用;
  • 变量:主要有三种类型的变量,局部变量、类变量(静态变量)、成员变量(非静态变量)

  • 异常处理

    • 异常是程序中的一些错误,但并不是所有的错误都是异常
    • 有三种类型的异常
      • 检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了
      • 运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
      • 错误:错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
      • 通常不捕获错误,错误一般发生在严重故障时,一般地,程序不会从错误中恢复;
    • 所有的异常类是从 java.lang.Exception 类继承的子类。
    • Exception 类是 Throwable 类的子类。除了Exception类外,Throwable还有一个子类Error 。
    • 异常类有两个主要的子类:IOException 类和 RuntimeException 类。
    • Java 语言定义了一些异常类在 java.lang 标准包中。java.lang 包是默认加载到所有的 Java 程序的,
    • 捕获异常:
      • 使用 try 和 catch 关键字可以捕获异常, finally;
      • throws/throw 关键字,throw 关键字用于在代码中抛出异常,而 throws 关键字用于在方法声明中指定可能会抛出的异常类型。
      • 一个方法可以声明抛出多个异常,多个异常之间用逗号隔开。
      • public void withdraw(double amount) throws RemoteException, InsufficientFundsException {}
    • try-with-resource
      • 语法糖来打开资源,并且可以在语句执行完毕后确保每个资源都被自动关闭;
      • try-with-resources 是一种异常处理机制,它可以简化资源管理代码的编写。
      • try (resource declaration) {// 使用的资源} catch (ExceptionType e1) { // 异常块}
      • 以上的语法中 try 用于声明和实例化资源,catch 用于处理关闭资源时可能引发的所有异常。
      • try-with-resources 可以声明多个资源,方法是使用分号 ; 分隔各个资源,来处理多个资源;
    • 声明自定义异常
      • 如果希望写一个检查性异常类,则需要继承 Exception 类。
      • 如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。
      • class MyException extends Exception{}
    • 通用异常
      • 在Java中定义了两种类型的异常和错误。
      • JVM(Java虚拟机) 异常:由 JVM 抛出的异常或错误。例如:NullPointerException 类
      • 程序级异常:由程序或者API程序抛出的异常。例如 IllegalArgumentException 类,IllegalStateException 类。
  • 多线程

    • Java 给多线程编程提供了内置的支持
    • 提供了三种创建线程的方法:
      • 通过实现 Runnable 接口;
      • 通过继承 Thread 类本身;
      • 通过 Callable 和 Future 创建线程。
    • 使用继承 Thread 类的方式创建多线程时,编写简单,如果需要访问当前线程,直接使用 this 即可获得当前线程;
    • 在多线程编程时,你需要了解以下几个概念:
      • 线程同步
      • 线程间通信
      • 线程死锁
      • 线程控制:挂起、停止和恢复

面向对象

  • 类分不同的类型:抽象类、final类、内部类、匿名类;

  • 修饰符

    • 使用修饰符来修饰类中方法和属性。主要有两类修饰符
    • 访问控制修饰符 : default, public , protected, private
    • 非访问控制修饰符 : final, abstract, static, synchronized
  • 构造方法:

    • 一个类可以有多个构造方法
    • 每个类都有构造方法。如果没有显式地为类定义构造方法,Java 编译器将会为该类提供一个默认构造方法。
    • 创建对象:声明一个对象,包括对象名称和对象类型、使用 new 创建对象时;
  • 源文件声明规则

    • 一个源文件中定义多个类,并且还有import语句和package语句
    • 一个源文件中只能有一个 public 类,源文件的名称应该和 public 类的类名保持一致;
    • 如果一个类定义在某个包中,那么 package 语句应该在源文件的首行。
  • 抽象类

    • 除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
    • 抽象类必须被继承,才能被使用,抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口;
    • 使用 abstract class 来定义抽象类,可以通过extends方式继承 Employee 类的属性;
    • 抽象方法,该方法的具体实现由它的子类确定;
    • public abstract double computePay();
    • 继承抽象方法的子类必须重写该方法。否则,该子类也必须声明为抽象类。
  • 枚举:

    • 也是一个类,需要new
    • 枚举是一个特殊的类,一般表示一组常量
    • 枚举跟普通类一样可以用自己的变量、方法和构造函数,构造函数只能使用 private 访问修饰符,所以外部无法调用
    • 类内部类中也可以使用枚举;
    • values(), ordinal() 和 valueOf() 方法,返回枚举类中所有的值,ordinal()方法可以找到每个枚举常量的索引,就像数组索引一样;
  • 包(package)

    • 为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。
    • package animals,通常使用小写的字母来命名避免与类、接口名字的冲突;
    • 把包里面的文件放在一个叫做animals的子目录中,包名和文件名一样;
    • import语句:
      • 用来提供一个合理的路径,使得编译器可以找到某个类。
      • import 关键字用于引入其他包中的类、接口或静态成员,引入之后就可以在当前源文件中直接使用类的方法、变量或常量;
    • 可以使用通配符 * 来引入整个包或包的子包:import com.runoob.mypackage.*;
  • package 的目录结构

    • 通常,一个公司使用它互联网域名的颠倒形式来作为它的包名.例如:所有的包名都以com.runoob 开头。包名中的每一个部分对应一个子目录。
    • 编译的时候,编译器为包中定义的每个类、接口等类型各创建一个不同的输出文件,输出文件的名字就是这个类型的名字,并加上 .class 作为扩展后缀
    • 这样就可以将你的类目录分享给其他的编程人员,而不用透露自己的源码。用这种方法管理源码和类文件可以让编译器和java虚拟机(JVM)可以找到;
    • 类目录的绝对路径叫做 class path。设置在系统变量 CLASSPATH 中;
    • 一个 class path 可能会包含好几个路径,多路径应该用分隔符分开。默认情况下,编译器和 JVM 查找当前目录。