JavaSE(简介)

1. Java语言特性

  1. 简单

Java语法是C++语法的一个“纯净版本”,相当于对C++做了一个减法。这里没有头文件、指针运算(甚至指针 语法)、结构、联合、操作符重载、虚基类等等。不仅如此,Java开发环境远远超出大多数其他编程语言的开 发环境。

  1. 面相对象

在Java的世界里,一切皆对象。比如:人、狗、手机、电脑等都是对象。所谓面相对象,就是依靠对象之间 的交互来完成事情。

  1. 分布式(微服务)

Java有丰富的例程库,用于处理像HTTP和FTP之类的TCP/IP协议。Java应用程序能够通过URL打开和访问网络
上的对象,其便捷程度就好像访问本地文件一样。

  1. 健壮性

Java采用的指针模型可以消除重写内存和损坏数据的可能性,Java编译器能够 检测许多在其他语言中仅在运行时才能够检测出来的问题。

  1. 安全性

Java适用于网络/分布式环境。为了达到这个目标,在安全性方面投入了大量的精力。使用Java可以构建防病
毒、防篡改的系统

  1. 体系结构中立

在这里插入图片描述
编译器生成一个体系结构中立的目标文件格式,按照该中规范生成的文件,只要有Java运行时系统,这些编译后的代码就可以在许多处理器上运行。Java编译器通过生成与特定计算机体系结构无关的字节码指令来实现 这一特性。字节码不仅可以很容易的在任何机器上解释执行,而且还可以动态地翻译成本地机器代码。“Wrice once,Run anywhere”。其他语言编写的程序,在编译后如果能够严格按照字节码文件的规范生成.class文件,也可以在JVM上运行。
在这里插入图片描述

7.可移植性

在Java中,数据类型具有固定的大小,这消除了代码移植时的主要问题。

  1. 解释性

Java为了实现与平台无关,自己维护了一套基于栈架构的指令集,Java源代码经过编译之后,字节码文件中的指令就是按照自己的指令集来组织的,但是在具体硬件环境中运行时,系统并不能识别,因为Java程序在执行 时,Java解释器会逐条的将字节码文件中的指令翻译成CPU的指令集。

  1. 高性能

边解释边执行,垃圾回收等导致了Java代码运行效率偏低,近年来JVM也在不断的优化,比如:JIT(即时编译器),热点代码探测,让Java程序的执行效率大幅提高。

  1. 多线程

Java是第一个支持并发程序设计的主流语言,多线程可以带来更好的交互响应和实时行为。

  1. 动态性

它能够适应不断发展的环境,库中可以自由的添加新方法和实例变量,而对客户端没有任何影响。在Java中找出运行时类型信息十分简单。Java不仅仅是一门编程语言,也是一个由一些列计算机软件和规范组成的技术体系。在这里插入图片描述

2. Java程序的运行

Java是一门半编译型、半解释型语言。先通过javac编译程序把源文件进行编译,编译后生成的.class文件是由字节 码组成的平台无关、面向JVM的文件。最后启动java虚拟机来运行.class文件,此时JVM会将字节码转换成平台能够 理解的形式来运行。在这里插入图片描述
在运行Java程序前,必须先安装好JDK(Java Development Kit即Java开发工具包),JDK里面就包含了javac和 java工具,Java程序最终是在JVM(Java虚拟机)中运行的。

JDK、JRE、JVM之间的关系:
在这里插入图片描述

  • JDK(Java Development Kit):Java开发工具包,提供给Java程序员使用,包含了JRE,同时还包含了编译器javac与自带的调试工具Jconsole、jstack等。
  • JRE(Java Runtime Environment):Java运行时环境,包含了JVM,Java基础类库。是使用Java语言编写程 序运行的所需环境。
  • JVM:Java虚拟机,运行Java代码

3. 关键字

  • 用于定义访问权限修饰符:private, protected, public,default
  • 用于定义类,函数,变量修饰符:abstract, final, static, synchronized
  • 用于定义类与类之间的关系:extends,implements
  • 用于定义建立实例及引用实例,判断实例:new,this,super,instanceof
  • 用于异常处理:try,catch,finally,throw,throws
  • 用于包:package,import
  • 其他修饰符关键字:native,strictfp,transient,volatile,assert

4. 注释

  • 单行注释:// 注释内容(用的最多)
  • 多行注释:/* 注释内容*/(不推荐)
  • 文档注释: /** 文档注释 */(常见于方法和类之上描述方法和类的作用),可以被javadoc工具解析,生 成一套以网页文件形式体现的程序说明文档
  1. 多行注释不能嵌套使用
  2. 不论是单行还是多行注释,都不参与编译,即编译之后生成的.class文件中不包含注释信息。

5. 标识符

在程序中由用户给类名、方法名或 者变量所取的名字。

由数字,字母,下划线,美元符号组成,
不能以数字、关键字开头,且严格区分大小写。

建议 :

  • 类名 :每个首字母大写(大驼峰)
  • 方法名:首字母小写,后面每个字母的首字母大写(小驼峰)
  • 变量名:首字母小写,后面每个字母的首字母大写(小驼峰)

6. 字面常量

常量即程序运行期间,固定不变的量称为常量

示例:

System.Out.println("Hello World")

不论程序何时运行,输出的都是Hello World,其实"Hello World"就是字面常量。

6.1 字面常量的分类

  1. 字符串常量:由""括起来的,比如“12345”、“hello”、“你好”。
  2. 整形常量:程序中直接写的数字(注意没有小数点),比如:100、1000 。
  3. 浮点数常量:程序中直接写的小数,比如:3.14、0.49。
  4. 字符常量:由 单引号 括起来的当个字符,比如:‘A’、‘1’。
  5. 布尔常量:只有两种true和false。
  6. 空常量:null。

7. 数据类型

7.1 四类基本数据类型

整型,浮点型,字符型,布尔型

7.1.1 八种

byte,short,int,long,float,double,char,boolean。
在这里插入图片描述

  • 不论是在16位系统还是32位系统,int都占用4个字节,long都占8个字节
  • 整形和浮点型都是带有符号的
  • 整型默认为int型,浮点型默认为double

字节是计算机中表示空间大小的基本单位.
计算机使用二进制表示数据. 我们认为 8 个二进制位(bit) 为一个字节(Byte). 我们平时的计算机为 8GB 内存, 意思是 8G 个字节.其中 1KB = 1024 Byte, 1MB = 1024 KB, 1GB = 1024 MB.所以 8GB 相当于 80 多亿个字节.

7.2 引用数据类型String

7.2.1 String类的构造方式:

使用常量串构造:
直接newString对象:
使用字符数组进行构造:

String是引用类型,内部并不存储字符串本身,在JDK1.8中,字符串实际保存在char类型的数组中。在Java中“”引起来的也是String类型对象。

7.2.1.1 字符串常量池:

为了节省存储空间以及程序的运行效率,Java中引入了:

  • Class文件常量池:
    每个.Java源文件编译后生成.Class文件中会保存当前类中的字面常量以及符号信息。
  • 运行时常量池:
    在.Class文件被加载时,.Class文件中的常量池被加载到内存中称为运行时常量池,运行时常量池每个类都有一份。
  • 字符串常量池:
    字符串常量池在JVM中是StringTable类,实际是一个固定大小的HashTable在堆中 ,大小可设置,有范围限制,最小是1009。
7.2.1.2 String对象创建的区别:
  • 直接使用字符串常量进行赋值:
    在字节码文件加载时,常量串已经加载好了并保存在字符串常量池中,创建对象时,先在字符串常量池中找,将字符串引用赋值给对象。使用常量串创建String类型对象的效率更高,而且更节省空间,也可以将创建的字符串对象通过 intern 方式添加进字符串常量池中。
  • 通过new创建String类对象:
    只要是new的对象,都是唯一的。
  1. String str = “hello”:
    只会开辟一块堆内存空间,保存在字符串常量池中,然后str共享常量池中的String对象。
  2. String str = new String(“hello”):
    会开辟两块堆内存空间,字符串"hello"保存在字符串常量池中,然后用常量池中的String对象给新开辟的String对象赋值。
  3. String str = new String(new char[]{‘h’, ‘e’, ‘l’, ‘l’, ‘o’}):
    先在堆上创建一个String对象,然后利用copyof将重新开辟数组空间,将参数字符串数组中内容拷贝到String对象中。
7.2.1.3 字符串的不可变性:

String是一种不可变对象. 字符串中的内容是不可改变。
String类中的字符实际保存在内部维护的value字符数组中,而且String类被final修饰表明该类不能被继承,value被修饰被final修饰表明value自身的值不能改变,即不能引用其它字符数组,但是其引用空间中的内容可以修改。

final修饰类表明该类不想被继承,final修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内容是可以修改的。所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象。

7.2.1.3.1 为什么 String 要设计成不可变的?
  1. 方便实现字符串对象池. 如果 String 可变, 那么对象池就需要考虑写时拷贝的问题了.
  2. 不可变对象是线程安全的.
  3. 不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中

7.2.2 String对象的比较:

  • ==
    比较是否引用同一个对象(对于内置类型,== 比较的是变量中的值;对于引用类型 == 比较的是引用中的地址)。

  • boolean equals(Object anObject) 方法
    按照字典序(字符大小的顺序)比较。先检测this 和 anObject 是否为同一个对象比较,如果是返回true,检测anObject是否为String类型的对象,如果是继续比较,否则返回false,将anObject向下转型为String类型对象,this和anObject两个字符串的长度是否相同,是继续比较,否则返回false,按照字典序,从前往后逐个字符进行比较。

  • int compareTo(String s) 方法
    按照字典序进行比较:1. 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值,2. 如果前k个字符相等(k为两个字符长度最小值),返回两个字符串长度差值。

  • int compareToIgnoreCase(String str) 方法:与compareTo方式相同,但是忽略大小写比较。

7.2.3 字符串查找:

  • char charAt(int index):返回index位置上字符,如果index为负数或者越界,抛出IndexOutOfBoundsException异常。
  • int indexOf(int ch) :返回ch第一次出现的位置,没有返回-1。
    int indexOf(int ch, int fromIndex):从fromIndex位置开始找ch第一次出现的位置,没有返回-1。
  • int indexOf(String str):返回str第一次出现的位置,没有返回-1。
  • int indexOf(String str, intfromIndex):从fromIndex位置开始找str第一次出现的位置,没有返回-1。
  • int lastIndexOf(int ch):从后往前找,返回ch第一次出现的位置,没有返回-1。
  • int lastIndexOf(int ch, int fromIndex):从fromIndex位置开始找,从后往前找ch第一次出现的位置,没有返回-1。
    int lastIndexOf(String str) :从后往前找,返回str第一次出现的位置,没有返回-1。
  • int lastIndexOf(String str, int fromIndex):从fromIndex位置开始找,从后往前找str第一次出现的位置,没有返回-1。

7.2.4 转化:

  • 数值和字符串转化:Integer.parseInt()Double.parseDouble()……
  • 大小写转换:toUpperCase(),toLowerCase()。
  • 字符串转数组:toCharArray(),
  • 数组转字符串:new String(ch)
  • 格式化:format(“%d-%d-%d”, 2019, 9,14)

7.2.5 替换:

  • 替换所有的指定内容:String replaceAll(String regex, String replacement)
  • 替换首个内容:String replaceFirst(String regex, String replacement)

由于字符串是不可变对象, 替换不修改当前字符串, 而是产生一个新的字符串。

7.2.6 字符串拆分:

  • 将字符串全部拆分:String[] split(String regex)
  • 将字符串以指定的格式,拆分为limit组:String[] split(String regex, int limit)

字符"|“,”*“,”+“都得加上转义字符,前面加上 “\” .
而如果是 “” ,那么就得写成 “\\” .
如果一个字符串中有多个分隔符,可以用”|"作为连字符.

7.2.7 字符串截取:

  • 从指定索引截取到结尾:String substring(int beginIndex)
  • 截取部分内容:String substring(int beginIndex, int endIndex) 注意前闭后开区间的写法, substring(0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标

7.2.8 字符串修改:

尽量避免直接对String类型对象进行修改,因为String类是不能修改的,所有的修改都会创建新对象,效率非常低下,如果要修改建议尽量使用StringBuffer或者StringBuilder。

7.2.8.1 String和StringBuilder类转换。
  • String变为StringBuilder: 利用StringBuilder的构造方法或append()方法。
  • StringBuilder变为String: 调用toString()方法。
7.2.8.2 String、StringBuffer、StringBuilder的区别:
  • String的内容不可修改,StringBuffer与StringBuilder的内容可以修改。
  • StringBuffer与StringBuilder大部分功能是相似的。
  • StringBuffer采用同步处理,属于线程安全操作;而- StringBuilder未采用同步处理,属于线程不安全操作。

7.2.9 其他方法

  • 去掉字符串中的左右空格,保留中间空格:String trim() ,trim 会去掉字符串开头和结尾的空白字符(空格, 换行, 制表符等)
  • 字符串转大写:String toUpperCase()
  • 字符串转小写:String toLowerCase()

8. 枚举类型

在Java当中枚举实际上就是一个类,将常量组织起来统一进行管理,是 java.lang.Enum 的子类,也就是说,自己写的枚举类,就算没有显示的继承 Enum ,但是其默认继承了这个类。枚举的构造方法默认是私有的。枚举常量更简单安全 。 枚举具有内置方法 ,代码更优雅,但是不可继承,无法扩展。应用场景:错误状态码,消息类型,颜色的划分,状态机等等…

Enum 类的常用方法:
以数组形式返回枚举类型的所有成员values() ;获取枚举成员的索引位置ordinal() ;将普通字符串转换为枚举实例valueOf() ;比较两个枚举成员在定义时的顺序compareTo()。

9. 变量

有些内容可能会经常改变,在Java程序中,称为变量,数据类型就是用来定义不同种类变量的。

9.1 语法格式

数据类型  变量名 = 初始值;

示例:

int a = 10;   // 定义整形变量a,a是变量名也称为标识符,该变量中放置的值为10

double d = 3.14; 
char c = 'A'; 
boolean b = true;

9.2 整型(int)变量

  1. int不论在何种系统下都是4个字节
  2. 如果没有合适的初始值,可以设置为0
  3. 在给变量设置初始值时,值不能超过int的表示范围,否则会导致溢出
  4. 变量在使用之前必须要赋初值,否则编译报错
  5. int的包装类型为 Integer

9.3 长整型(long)变量

  1. 长整型变量的初始值后加L或者l,推荐加L
  2. 长整型不论在那个系统下都占8个字节
  3. 长整型的表示范围为: ~
  4. long的包装类型为Long

9.4 短整型(short)变量

  1. short在任何系统下都占2个字节
  2. short的表示范围为:-32768 ~ 32767
  3. 使用时注意不要超过范围(一般使用比较少)
  4. short的包装类型为Short

9.5 字节型(byte)变量

  1. byte在任何系统下都占1个字节
  2. byte的范围是:-128 ~ 127
  3. 字节的包装类型为Byte

9.6 双精度浮点型(double)变量

  1. double在任何系统下都占8个字节
  2. 浮点数与整数在内存中的存储方式不同,不能单纯使用 的形式来计算
  3. double的包装类型为Double
  4. double 类型的内存布局遵守 IEEE 754 标准(和C语言一样), 尝试使用有限的内存空间表示可能无限的小数, 势
    必会存在一定的精度误差,因此浮点数是个近似值,并不是精确值。
  5. 在 Java 中, int 除以 int 的值仍然是 int(会直接舍弃小数部分)。如果想得到 0.5, 需要使用 double 类型计算.

9.7 单精度浮点型(float)变量

float 类型在 Java 中占四个字节, 同样遵守 IEEE 754 标准. 由于表示的数据精度范围较小, 一般在工程上用到浮点数 都优先考虑 double, 不太推荐使用 float. float的包装类型为Float。

9.8 字符型(char)变量

  1. Java 中使用 单引号 + 单个字母 的形式表示字符字面值.
  2. 计算机中的字符本质上是一个整数. 在 C 语言中使用 ASCII 表示字符, 而 Java 中使用 Unicode 表示字符. 因此 一个字符占用两个字节, 表示的字符种类更多, 包括中文.
  3. char的包装类型为Character

9.9 布尔型(boolean)变量

  1. boolean 类型的变量只有两种取值, true 表示真, false 表示假.
  2. Java 的 boolean 类型和 int 不能相互转换, 不存在 1 表示 true, 0 表示 false 这样的用法.

9.10 类型转换

Java 是一个强类型编程语言, 当不同类型之间的变量相互赋值的时候, 会有教严格的校验.

  1. 不同数字类型的变量之间赋值, 表示范围更小的类型能隐式转换成范围较大的类型
  2. 如果需要把范围大的类型赋值给范围小的, 需要强制类型转换, 但是可能精度丢失
  3. 将一个字面值常量进行赋值的时候, Java 会自动针对数字范围进行检查
  4. 强制类型转换不一定能成功,不相干的类型不能互相转换

9.10.1 自动类型转换(隐式)

代码不需要经过任何处理,在代码编译时,编译器会自动进行处理。数据范围小的转为数 据范围大的时会自动进行。

9.10.1 强制类型转换(显式)

当进行操作时,代码需要经过一定的格式处理,不能自动完成。
特点:数据范围大的到数据范围小的。

9.11 类型提升

不同类型的数据之间相互运算时,数据类型小的会被提升到数据类型大的。

  1. int与long之间:int会被提升为long
  2. byte与byte的运算:
    byte a = 10; 
    byte b = 20; 
    byte c = a + b;
    System.out.println(c);
    
    // 编译报错
    Test.java:5: 错误: 不兼容的类型:int转换到byte可能会有损失 
    
    byte 和 byte 都是相同类型, 但是出现编译报错. 原因是, 虽然 a 和 b 都是 byte, 但是计算 a + b 会先将 a 和 b 都提升成 int, 再进行计算, 得到的结果也是 int, 这是赋给 c, 就会出现上述错误.由于计算机的 CPU 通常是按照 4 个字节为单位从内存中读写数据. 为了硬件上实现方便, 诸如 byte 和 short 这种低于 4 个字节的类型, 会先提升成 int, 再参与计算。
    正确的写法:
    byte a = 10; 
    byte b = 20; 
    byte c = (byte)(a + b);
    System.out.println(c);
    

10. 数组

  • 数组数组是引用类型,可以看成是相同类型元素的一个集合,在内存中是一段连续的空间。
    1. 数组中存放的元素其类型相同
    2. 数组的空间是连在一起的
    3. 每个空间有自己的编号,其实位置的编号为0,即数组的下标。在这里插入图片描述

10.1 数组的创建格式


T[] 数组名 = new T[N];


10.2 数组的初始化

如果没有对数组进行初始化,数组中元素有其默认值,如果数组中存储元素类型为引用类型,默认值为null, 如果数组中存储元素类型为基类类型,默认值为基类类型对应的默认值在这里插入图片描述

  1. 动态初始化:在创建数组时,直接指定数组中元素的个数
int[] array = new int[10];
  1. 静态初始化:在创建数组时不直接指定数据元素个数,而直接将具体的数据内容进行指定
    T[] 数组名称 = {data1, data2, data3, ..., datan}
    
    int[] array1 = new int[]{0,1,2,3,4,5,6,7,8,9};
    double[] array2 = new double[]{1.0, 2.0, 3.0, 4.0, 5.0}; 
    String[] array3 = new String[]{"hell", "Java", "!!!"};
    

静态初始化时, {}中数据类型必须与[]前数据类型一致。
静态初始化虽然没有指定数组的长度,编译器在编译时会根据{}中元素个数来确定数组的长度。
静态初始化可以简写,省去后面的new T[]。
静态和动态初始化也可以分为两步,但是省略格式不可以。

int[] array1;
array1 = new int[10];

int[] array2;
array2 = new int[]{10, 20, 30};

// 注意省略格式不可以拆分, 否则编译失败 // int[] array3;
// array3 = {1, 2, 3};

10.3 数组的使用

10.3.1 数组中元素访问

数组在内存中是一段连续的空间,空间的编号都是从0开始的,依次递增,该编号称为数组的下标,支持随机访问,数组可以通过下标访问其任意位置的元素。下标从0开始,介于[0, N)之间不包含N,N为元素个数,不能越界,否则会报出下标越界异常。

int[]array = new int[]{10, 20, 30, 40, 50}; 
System.out.println(array[0]);
System.out.println(array[1]);
System.out.println(array[2]); 
System.out.println(array[3]);
System.out.println(array[4]);

10.3.2 遍历数组

“遍历” 是指将数组中的所有元素都访问一遍, 访问是指对数组中的元素进行某种操作。


int[]array = new int[]{10, 20, 30, 40, 50}; 
for(int i = 0; i < array.length; i++){ 
    System.out.println(array[i]);
}    


int[] array = {1, 2, 3};
for (int x : array) { 
    System.out.println(x);
}

10.4 数组的存储

基本数据类型创建的变量,称为基本变量,该变量空间中直接存放的是其所对应的值; 而引用数据类型创建的变量,一般称为对象的引用,其空间中存储的是对象所在空间的地址。
引用变量并不直接存储对象本身,可以简单理解成存储的是对象在堆中空间的起始地址。通过该地址,引用变量便可以去操作对象。

示例:


 public static void func() { 
    int a = 10;
    int b = 20;
    int[] arr = new int[]{1,2,3};
 }   
 

在上述代码中,a、b、arr,都是函数内部的变量,因此其空间都在main方法对应的栈帧中分配。 a、b是内置类型的变量,因此其空间中保存的就是给该变量初始化的值。 array是数组类型的引用变量,其内部保存的内容可以简单理解成是数组在堆空间中的首地址。在这里插入图片描述

10.4.1 数组的修改

public static void func() { 
    int[] array1 = new int[3];
    array1[0] = 10; 
    array1[1] = 20; 
    array1[2] = 30;
    int[] array2 = new int[]{1,2,3,4,5}; 
    array2[0] = 100;
    array2[1] = 200;
    array1 = array2; 
    array1[2] = 300; 
    array1[3] = 400; 
    array2[4] = 500; 
    for (int i = 0; i < array2.length; i++) {
       System.out.println(array2[i]); 
    }

在这里插入图片描述
在这里插入图片描述

10.4.2 数组拷贝

  1. 借助copyOf() 方法
import java.util.Arrays;

public static void func(){
    // newArr和arr引用的是同一个数组
    // 因此newArr修改空间中内容之后,arr也可以看到修改的结果 
    int[] arr = {1,2,3,4,5,6};
    int[] newArr = arr;
    newArr[0] = 10;
    System.out.println("newArr: " + Arrays.toString(arr));

    // 使用Arrays中copyOf方法完成数组的拷贝:
    // copyOf方法在进行数组拷贝时,创建了一个新的数组
    // arr和newArr引用的不是同一个数组
    arr[0] = 1;
    newArr = Arrays.copyOf(arr, arr.length); 
    System.out.println("newArr: " + Arrays.toString(newArr));

    // 因为arr修改其引用数组中内容时,对newArr没有任何影响 
    arr[0] = 10;
    System.out.println("arr: " + Arrays.toString(arr)); 
    System.out.println("newArr: " + Arrays.toString(newArr));

    // 拷贝某个范围.
    int[] newArr2 = Arrays.copyOfRange(arr, 2, 4); 
    System.out.println("newArr2: " + Arrays.toString(newArr2));
}

在这里插入图片描述在这里插入图片描述

  1. 实现copyOf()
public static int[] copyOf(int[] arr) { 
    int[] ret = new int[arr.length]; 
    for (int i = 0; i < arr.length; i++) { 
        ret[i] = arr[i];
    }
    return ret;
}

10.4 二维数组

  1. 基本语法

数据类型[][] 数组名称 = new 数据类型 [行数][列数] { 初始化数据 };

使用示例:


int[][] arr = { 
    {1, 2, 3, 4}, 
    {5, 6, 7, 8}, 
    {9, 10, 11, 12}
};

for (int row = 0; row < arr.length; row++) { 
    for (int col = 0; col < arr[row].length; col++) { 
        System.out.printf("%d\t", arr[row][col]);
    }
    System.out.println("");



// 执行结果
1       2       3       4
5       6       7       8
9       10      11      12

10.5 数组练习

10.5.1 求数组中元素的平均值

public static void main(String[] args) { 
    int[] arr = {1,2,3,4,5,6}; 
    System.out.println(avg(arr));
}
public static double avg(int[] arr) {
    int sum = 0;
    for (int x : arr) {
        sum += x;
    }
    return (double)sum / (double)arr.length;
}


// 执行结果 
3.5

10.5.2 查找数组中指定元素(顺序查找)

public static void main(String[] args) { 
    int[] arr = {1,2,3,10,5,6}; 
    System.out.println(nd(arr, 10));
}

public static intnd(int[] arr, int data) { 
    for (int i = 0; i < arr.length; i++) { 
        if (arr[i] == data) {
            return i;
        }
    }
    return -1;  // 表示没有找到   
}

// 执行结果
3

10.5.3 查找数组中指定元素(二分查找)

针对有序数组, 可以使用更高效的二分查找.
以升序数组为例, 二分查找的思路是先取中间位置的元素, 然后使用待查找元素与数组中间元素进行比较: 如果相等,即找到了返回该元素在数组中的下标
如果小于,以类似方式到数组左半侧查找 如果大于,以类似方式到数组右半侧查找

public static void main(String[] args) { 
    int[] arr = {1,2,3,4,5,6}; 
    System.out.println(binarySearch(arr, 6));
}

public static int binarySearch(int[] arr, int toFind) { 
    int left = 0;
    int right = arr.length - 1;
    while (left <= right) {   
             int mid = (left + right) / 2; 
        if (toFind < arr[mid]) { 
            // 去左侧区间找 
            right = mid - 1;
        } else if (toFind > arr[mid]) { 
            // 去右侧区间找
            left = mid + 1;
        } else {
            // 相等, 说明找到了 
            return mid;
        }
    }
    // 循环结束, 说明没找到 
    return -1;
}

// 执行结果
5

10.5.4 冒泡排序

假设排升序:

  1. 将数组中相邻元素从前往后依次进行比较,如果前一个元素比后一个元素大,则交换,一趟下来后最大元素 就在数组的末尾
  2. 依次从上上述过程,直到数组中所有的元素都排列好
public static void main(String[] args) { 
    int[] arr = {9, 5, 2, 7};
    bubbleSort(arr); 
    System.out.println(Arrays.toString(arr));
}
public static void bubbleSort(int[] arr) { 
    for (int i = 0; i < arr.length; i++) { 
        for (int j = 1; j < arr.length-i; j++) { 
            if (arr[j-1] > arr[j]) {
                int tmp = arr[j - 1]; 
                arr[j - 1] = arr[j];
                arr[j] = tmp;
            }
        }
    } // end for
}  // end bubbleSort    


// 执行结果
[2, 5, 7, 9]

Java 中内置了更高效的排序算法:

public static void main(String[] args) { 
   int[] arr = {9, 5, 2, 7};
   Arrays.sort(arr); 
   System.out.println(Arrays.toString(arr));
}    

10.5.5 数组逆序

设定两个下标, 分别指向第一个元素和最后一个元素. 交换两个位置的元素.
然后让前一个下标自增, 后一个下标自减, 循环继续即可.

public static void main(String[] args) { 
    int[] arr = {1, 2, 3, 4};
    reverse(arr); 
    System.out.println(Arrays.toString(arr));
}

public static void reverse(int[] arr) { 
    int left = 0;
    int right = arr.length - 1;
    while (left < right) {
        int tmp = arr[left];
        arr[left] = arr[right]; 
        arr[right] = tmp;
        left++;
        right--; 
    }
}

11. 运算符

  • 算术运算符:±*/

  • 增量运算符:+= -= *= %=

  • 自增自减运算符:++ –

  • 关系运算符:== ,!=,<,>,<=,>=

  • 逻辑运算符:&&,||,!

  • 位运算符:

    • &(如果两个二进制位都是 1, 则结果为 1, 否则结果为 0)
    • |(如果两个二进制位都是 0, 则结果为 0, 否则结果为 1)
    • ^ (如果两个数字的二进制位相同, 则结果为 0, 相异则结果为 1)
    • ~(如果该位为 0 则转为 1, 如果该位为 1 则转为 0)
  • 移位运算符:

    
    <<(最左侧位不要了, 最右侧补 0>>(最右侧位不要了, 最左侧补符号位(正数补0, 负数补1)>>>(最右侧位不要了, 最左侧补 0
  • 条件运算符:表达式1 ? 表达式2 : 表达式3

13. 逻辑控制

顺序结构:按照代码书写的顺序一行一行执行。
分支结构:if,switch(只能是以下类型:byte、char、short、int,String常量串、枚举类型)
循环结构:
while(break(让循环提前结束),continue(跳过这次循环, 立即进入下次循环)),for,do while

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/478869.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ttkbootstrap界面美化系列之按钮Button(三)

目录 一&#xff1a;Button接口 二&#xff1a;Button创建 三&#xff1a;Button主题 四&#xff1a;Button样式 五&#xff1a;Button状态 从本章开始将详细介绍ttkbootstrap中支持的常用组件&#xff0c;从按钮BUTTON开始&#xff0c;在各类界面设计中按钮几乎是必不可少…

解锁AI生成模型的无限可能:Stability-AI 带你领略前沿科技

厌倦了千篇一律的图片和视频&#xff1f;想要创作独一无二的艺术作品&#xff1f;Stability-AI 横空出世&#xff0c;为你打开通往 AI 生成模型的大门&#xff0c;带你领略前沿科技的无限可能&#xff01; 神奇的功能&#xff0c;尽在掌握 Stability-AI 拥有众多令人惊叹的功能…

第2讲-Memory(4)拓展

存储器芯片结构 存储器扩展 地址总线:这决定了处理器将从内存中读取数据或写入数据的内存位置。 数据总线:它包含已从内存位置读取或将写入内存位置的数据内容。 控制总线:它管理组件之间的信息流,指示操作是读取还是写入,并确保操作在正确的时间发生。

聊一下大模型的函数调用-Function call

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…

Springboot 利用自定义注解+切面,实现 查询数据集合时主动加序列字段

利用自定义注解切面,实现 查询数据集合时主动加序列字段, 只需要在Dao接口&#xff0c;方法上引入注解即可 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotat…

数据结构 - 链表

一.链表的概念 链表是一个在物理存储单元中不连续&#xff0c;没有顺序的的存储结构&#xff0c;关于它的顺序是由链表中的指针链接实现的&#xff0c;是一种递归的数据结构&#xff0c;链表有一系列节点组成&#xff0c;而这些节点会在运行时动态生成。 节点包括两个部分&am…

【docker】查看并拷贝容器内文件

一、查询容器 查询所有容器 docker ps查询名为os11的容器 docker ps | grep os11查询名为os11的容器&#xff08;包含不运行的&#xff09; docker ps -a| grep os11 docker ps [option] 显示结果介绍如下&#xff1a; 参考&#xff1a;[https://blog.51cto.com/u_15009374/31…

工厂投产、电池装车,广汽能上动力电池行业的“餐桌”吗?

文 | 智能相对论 作者 | 沈浪 “如果你不在餐桌上&#xff0c;你就会出现在菜单上。”在某种程度上&#xff0c;追逐效益的动力电池行业正在上演着布林肯的“餐桌菜单论”。 于是&#xff0c;我们可以看到&#xff0c;尽管整体的动力电池市场被宁德时代、比亚迪、LG新能源、…

怿星科技Neptune CHT-S测试系统,让智能座舱测试更加高效便捷

随着汽车“智能化”浪潮的推进&#xff0c;汽车的智能化水平正在持续刷新行业认知。在这股智能化潮流中&#xff0c;智能座舱作为客户体验最为直观的部分&#xff0c;其重要性不言而喻。倘若座舱设备出现死机、黑屏、卡顿等现象&#xff0c;都将对客户的使用体验产生非常大的影…

领军量子时代!逾九成机构加盟「英伟达」生态系统

在2024年3月17日至21日举行的GTC大会上&#xff0c;芯片制造领军企业英伟达&#xff08;NVIDIA&#xff09;发布了一项革命性的云服务&#xff0c;专为推动量子计算研究而设计。这一新服务&#xff0c;名为英伟达量子云&#xff08;NVIDIA Quantum Cloud&#xff09;&#xff0…

外包干了15天,技术退步明显。。。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;2019年我通过校招踏入了南京一家软件公司&#xff0c;开始了我的职业生涯。那时的我&#xff0c;满怀热血和憧憬&#xff0c;期待着在这个行业中闯出一片天地。然而&#xff0c;随着时间的推移&#xff0c;我发现自己逐渐陷入…

C# winform修改背景图 控件双向绑定 拖拽打开图片

修改背景图 说明 这里我准备基于百度飞桨PaddleSeg项目的人像分割模块做一个人像抠图&#xff0c;这里顺便用上了双向绑定和图片拖拽打开。 下面就是示例&#xff1a; 用颜色替换 用背景图替换 保存成功后的图片 一、使用百度飞桨PaddleSeg //初始化 引擎engine new Padd…

掌握未来技术:国产openEuler 操作系统学习网站指南!

介绍&#xff1a;openEuler是一个开源的操作系统平台&#xff0c;由华为技术有限公司发起并维护。 首先&#xff0c;openEuler支持多种处理器架构&#xff0c;包括但不限于AArch64&#xff08;鲲鹏&#xff09;和x86-64&#xff0c;这使得它可以在多种硬件平台上运行&#xff0…

滴水逆向PE结构

1.操作系统是只能打开可执行文件 以4D 5A开头MZ 其他的txt都是什么wrod 都是在exe程序中打开的 txt啥的不是可执行文件 PE结构是分节的 一节一节 节省硬盘空间 32位中任何一个exe都有4g的虚拟内存 占内存空间大 给磁盘空间小 在硬盘空间紧密 在内存空间大 &#xff08…

设计模式 --4:工厂方法模式

总结 &#xff1a; 个人理解&#xff1a; 工厂方法模式就是在简单工程模式的基础下将工厂类抽象出来。如果不抽象工厂类 &#xff0c;每一次创建一个新的算法&#xff0c;都要修改原来的工厂类&#xff0c;这不符合 开放–封闭原则 将工厂类给抽象出来&#xff0c;让具体的算法…

appium自动化框架综合实践

结合前面的元素寻找、操作、unittest测试框架&#xff0c;搭建一个完整的自动化框架。本篇旨在框架设计、单机用例执行、输出报告&#xff0c;下篇继续实践Bat批处理执行测试、多设备并发测试。 框架功能 数据配置日志输出截图处理基础功能封装&#xff08;公共方法&#xff…

Java学习笔记NO.24

T1.完成理工超市系统的商品类及其子类的定义&#xff0c;实现“浏览商品”及“查看商品详情”功能 &#xff08;1&#xff09;商品类 public class Goods {public String name;public double price;public int count;public String desc;public Goods(String name, double p…

敏捷开发——第二次作业JS/服务器的部署

部署 Web 服务器 1. 安装 Apache HTTP 服务器并部署静态网页应用 ⭐⭐ 默认情况下&#xff0c;Apache 在 /var/www/html 目录下寻找要提供服务的文件。可以将静态网页文件放置在这个目录下 2.安装 Nginx 并部署静态页面应用 3. 实践部分 1. 2. 3. 在 /var/www/html 目录下…

用大语言模型控制交通信号灯,有效缓解拥堵!

城市交通拥堵是一个全球性的问题&#xff0c;在众多缓解交通拥堵的策略中&#xff0c;提高路口交通信号控制的效率至关重要。传统的基于规则的交通信号控制&#xff08;TSC&#xff09;方法&#xff0c;由于其静态的、基于规则的算法&#xff0c;无法完全适应城市交通不断变化的…

又一款代码神器,效率直接翻倍!免费的还是香啊!

前言 提到商汤科技&#xff0c;你可能仍然将其与“AI四小龙”、“计算机视觉领军企业”等标签联系在一起。然而&#xff0c;在ChatGPT与Sora赢得广泛关注后&#xff0c;商汤科技依托其深厚的人工智能技术基础&#xff0c;迅速开发出自己的大型模型及人工智能应用产品&#xff…
最新文章