java基础-数据类型

2024-02-27

基本数据类型

byte
	-128 - 127
	1字节(8bit位)
short
	-2^15 - 2^15 - 1
	2字节
int
	-2^31 - 2^31 - 1
	4字节
long
	-2^63 - 2^63 - 1
	8字节
	定义时需要在尾部加L或l
		long num = 123L;
		long num = 123l;
	如果没加L并且数字没有超过int型长度,那么就会以int型展示
float
	-3.403E38 - 3.403E38
	4字节
	精度精确到7位
	定义时需要在尾部加F或f
		float num = 123F;
		float num = 123f;
double
	-1.798E308 - 1.798E308
	8字节
	精度精确到14位
char
	1字符占两个字节
	使用单引号声明
	内部只能写一个字符
	不能定义空字符
	可以定义ASCII值
boolean

类型转换

类型自动提升
	byte、char、short--->int--->long--->float--->double
	当byte、char、short三种类型变量做运算时,结果为int类型
强制转换
	(int) (long) (double) (float)
	不能对String的数字使用(int)进行转换
	大容量类型转换小容量类型时会导致精度丢失

引用数据类型

class、interface、String

数组

多个相同数据类型按一定顺序排列的集合,并使用一个名字命名,数组是有序排列的
数组的长度,长度一旦确定就不能修改
顺序表的一种,插入元素的效率不高
数组的元素可以是基本数据类型,也可以是引用数据类型

一维数组

声明

静态初始化

数组的初始化和数组元素的初始化同时进行


int[] ids = new int[]{1001, 1002, 1003 ,1004};

// 类型推断,声明且初始化时才可以使用,声明和初始化分开处理时,不能这么做
int[] ids = {1001, 1002, 1003 ,1004};
动态初始化

数组的初始化和数组元素的初始化分开进行

// 声明数组有5个元素
String[] names = new String[5];
String names[] = new String[5];

调用数组的指定位置的元素

names[0] = "123";
names[1] = "456";

获取数组的长度

int namesLen = names.length;

遍历数组

for (int i = 0; i < namesLen; i++) {
    System.out.println(names[i]);
}

数组元素的默认初始化值

声明元素后,未设置数组元素,这时访问数组的元素,会有一个初始化值
数组元素为整型时,默认初始化值为0
数组元素为浮点型时,默认初始化值为0.0
数组元素为char型时,默认初始化值为0或''
数组元素为boolean型时,默认初始化值为false
数组元素为String型时,默认初始化值为null

内存解析

堆
	存储new出来的对象【对象、数组】;生成数组长度的连续内存空间,首位地址(16进制地址)
栈
	存储局部变量;存储数组的变量名和数组元素在堆中的16进制地址

二维数组

声明

静态初始化
int[][] arr1 = new int[][]{{1, 2, 3}, {4, 5}};
int[][] arr1 = {{1, 2, 3}, {4, 5}};
动态初始化
String[][] arr2 = new String[5][2];
String[][] arr3 = new String[5][];
String arr4[][] = new String[5][];
String[] arr5[] = new String[5][];

调用数组的指定位置的元素

// 如果二维数组是动态初始化的,但是第二维的元素没有定义长度,这时调用将报错(空指针)
arr2[0][2] = "111";

获取数组的长度

int arr2Len = arr2.length;
int arr2FirstLen = arr2[0].length;

遍历数组

for (int i = 0; i < arr2Len; i++) {
      int arr2YLen = arr2[i].length;
      for (int j = 0; j < arr2YLen; j++) {					 
           System.out.println(arr2[i][j]);
      }
}

数组元素的默认初始化值

二维数组地址值: [[@15db9742
外层元素:地址值 [@15db9742
内层元素
	与一维数组一致

内存解析

堆
	生成数组长度的连续内存空间,首位地址(16进制地址),二维数组的元素在开辟一个内存空间,这个元素对比这个内存空间的首位地址
栈
	存储数组的变量名和数组元素在堆中的16进制地址

数组复制

int[] arr1 = new int[2]{1, 2};
// 浅拷贝,这时两个数组共享同一个内存地址,当其中一个数组的元素发生变化时,另一个数组也会发生变化
arr2 = arr1;

数组工具类Arrays

import java.util.Arrays
// 比较两个数组是否相等
boolean res = Arrays.equals(int[] a, int[] b)
// 输出数组信息,如果是多维数组将展示地址值
String res = Arrays.toString(int[] a)

// 将指定值填充到数组中
Arrays.fill(int[] a, int val)

// 数组排序
Arrays.sort(int a)
// 对排序后的数组进行二分法检索指定的值,得到索引值,负数表示没找到
int index = Arrays.binarySeatch(int[] a, int key)

常见异常

// 数组角标越界异常
ArrayIndexOutBoundsException
// 空指针异常,数组元素为null时,对这个元素做方法处理时,会触发空指针
NullPointerException:

打印

char[] arr1 = new char[]{'a', 'b', 'c'};
// char型数组打印时打印的是数组元素
System.out.println(arr1);

int[] arr = new int[]{1, 2, 3};
// 其他数据类型型数组打印时打印的是地址值
System.out.println(arr);

弊端

数组一旦初始化,其长度就不可变了。
数组中存储数据特点的单一性。对于无序的、不可重复的场景的多个数据就无能为力了
数组中可用的方法、属性都极少。
针对于数组中元素的删除、插入操作性能较差

ArrayList类

是一个可变容量的数组,底层基于数组实现容量大小动态可变

扩容机制

首先扩容为原始容量的 1.5 倍。如果1.5倍太小的话,则将我们所需的容量大小赋值给 newCapacity;
如果1.5倍太大或者我们需要的容量太大,那就直接拿 newCapacity = (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE 来扩容。 
扩容之后是通过数组的拷贝来确保元素的准确性的,所以尽可能减少扩容操作。 
ArrayList 的最大存储能力:Integer.MAX_VALUE。 
size为集合中存储的元素的个数。
elementData.length 为数组长度,表示最多可以存储多少个元素

数组容量

默认容量为10,使用无参构造器时是在第一次添加元素是初始化容量为10的
add、addAll操作都是先对集合容量检查 ,以确保不会数组越界。然后通过 System.arraycopy() 方法将旧数组元素拷贝至一个新的数组中去。
remove操作,首先会检查 index 是否合法,然后再判断要删除的元素是否位于数组的最后一个位置。
如果 index 不是最后一个,就再次调用 System.arraycopy() 方法拷贝数组;如果 index 是最后一个元素那么就直接将数组的最后一个位置空,size - 1即可

方法

import java.util.ArrayList;
// 定义
// E: 泛型数据类型,用于设置 objectName 的数据类型,只能为引用数据类型
ArrayList<E> objectName =new ArrayList<>();
// 支持类型
ArrayList<Boolean>
ArrayList<Byte>
ArrayList<Integer>
ArrayList<Long>
ArrayList<Float>
ArrayList<Double>
ArrayList<Character>
ArrayList<BigInteger>
ArrayList<BigDecimal>

// 向数组中添加元素

objectName.add("值1");

// 添加集合中的所有元素到数组中
objectName.addAll()
// 从数组中移除索引为0的元素
objectName.remove(0);
// 清空数组
objectName.removeAll()

// 获取数组的大小

objectName.size()

// 获取数组中指定索引的 
objectName.get(index)

// 获取元素在数组中的索引值
objectName.indexOf(value)

// 判断元素是否在数组中
objectName.contains(value)

// 遍历元素
objectName.forEach()
例:

object.forEach((e) -> {
   System.out.println(e);
})

排序

import java.util.Collections;
// 字母排序
Collections.sort(objectName);

// 数字排序
Collections.sort(objectName);

LinkedList类

元素插入效率比数组更高

实现了List接口和Queue接口,也就是它既可以看作是一个顺序容器,又可以看作是一个队列,同时又可以看作是一个栈

使用

import java.util.LinkedList;
// 初始化
List<String> list1 = new LinkedList<>();
List<String> list2 = new LinkedList<>(
    Arrays.asList(new String[]{"a", "b", "c"}
);
List<String> list3 = new LinkedList<>(){
    {
            add("china");
            add("english");
    }
};
// 在链表后添加一个元素,如果成功,返回true,否则返回false;
list1.add(value)
// 在指定位置插入一个元素。
list1.add(value, index)
// 在链表头部插入一个元素;
list1.addFirst(value)
list1.push(value)
// 在链表尾部添加一个元素;
list1.addLast(value)
list1.offer(value)
// 移除链表中第一个元素
list1.remove()
list1.removeFirst()
list1.pop()
// 移除链表中指定的元素;
list1.remove(index)
// 查询并移除第一个元素
list1.poll()
// 移除链表中最后一个元素
list1.removeLast()
// 获取指定索引的元素
list1.get(index)
// 获取第一个元素
list1.getFirst()
// 获取最后一个元素
list1.getLast()
// 获取第一个元素,但是不移除
list1.peek()
list1.peekFirst()
// 获取最后一个元素,但是不移除
list1.peekLast()


{/if}