Java中关于数组的工具类Arrays
Arrays是java中的工具类,在util包下,里面全是静态static方法
常用方法:
Arrays.toString(数组名);//直接遍历一维数组
Arrays.sort(int[] arr)//给数组arr排序
Arrays.sort(int[] arr, int fromIndex, int toIndex)//给数组arr从fromeIndex到toIndex排序
Arrays.binarySearch(int[] arr, int key)//查询数组中是否有key这个元素
Arrays.binarySearch(int[] arr,int fromIndex, int toIndex, int key)
//数组arr从fromeIndex到toIndex之间查询是否存在key
Arrays.copyOf(int[] arr, int newLength)//把原数组arr从0位置复制一个长度为newLength的新数组,对原数组arr无影响,这是一个有返回值的方法,产生了新数组
Arrays.copyOfRange(数组名, 开始下标, 结束下标)//可以复制数组newArr中的你输入的开始下标到结束下标的内容,但是不包含结束下标,这是一个有返回值的方法,产生了新数组
一维数组初始化
动态初始化:
int[] arrays = new int[数组长度];
静态初始化:
int[] arrays = {元素1,元素2,元素3,......};
动静结合初始化
int[] arrays = new int[] {元素1,元素2,元素3,......}
获取数组长度
//定义一个数组
int[] arrays = {1,3,4,1,4,6,8,8,9,10,22};
//获取数组长度
int t = arrays.length;
一维数组遍历打印
//定义一个数组
int[] arrays = {1,2,3,4,5,45,22,10}
//第一种:用数组下标来进行循环打印
for(int i = 0; i < arrays.length; i++){
System.out.println(arrays[i]);
}
//第二种:foreach遍历打印
for(int t : arrays){
System.out.println(t);
}
一维数组特点
1.数组中只能存储一组相同类型的数据
2.数组的长度(数据个数)是固定的,不能多也不能少,少的系统会给默认值补充
数组元素的默认值:
只要是数字类型(整数型、浮点型):0或者0.0
字符:空白字符'' (对应的数字0)--null
布尔:false
3.数组在内存中是一组连续的内存空间
4.数组是有序的(内存地址有序0,1,2,3......)
5.数组中可以存储重复的元素
注意:
/*
* 1. 当多个引用类型的变量,公用同一块内存空间,
* 某个变量,更改了该内存中的数据,其他正在引用的变量
* 再次使用该数据时,也是使用的改变之后的数据
*/
int[] a = new int[] {1,2,3};//a引用了一块内存
int[] b = a;//a,b公用一块内存空间
a[0] = 100;
System.out.print(b[0]);//b[0] == 100
/*
* 2. 多个引用类型的变量,公用同一块内存空间,
* 某个变量去引用其他内存空间,其他的不受影响,还用原来的
*/
int[] a = new int[] {1,2,3};//a引用了一块内存
int[] b = a;//a,b公用一块内存空间
a = null;
System.out.print(b[0]);//b[0] == 1
/*
* 3.
*null : 空 没有指定内存空间
*如果数组的值为null,除了打印以外,无法使用
*null 不能赋值给基本数据类型
*/
int[] array = null
一维数组插入一个元素值
import java.util.Scanner;
/**
* 给数组中插入元素
* @author Amid
*
*/
public class ArraysInsertNum{
static Scanner scanner = new Scanner(System.in);//从控制台获取数据的工具
public static void main(String[] args){
//定义一个长度为10的数组,这时还未给数组内元素进行赋值,所以这时候数组内元素的值都是默认值0
int[] arrays = new int[10];
giveNum(arrays);//调用giveNum方法,从控制台给数组内元素赋值
System.out.println("请输入你要插入位置的元素值");
//调用findIndex方法,获得arrays数组内某个值的下标
int index = findIndex(arrays,scanner.nextInt());
System.out.println("请输入你要插入的元素值");
//调用arraysInsertNum方法,获得插入元素后的新数组
//调用ergodicPrintArray方法遍历打印新数组
ergodicPrintArray( arraysInsertNum(arrays, index, scanner.nextInt()));
}
/**
* 从控制台给数组内元素赋值
* @param arrays
* @return
*/
static int[] giveNum(int[] arrays){//把定义的数组传进来
for(int i = 0; i < arrays.length; i++){//遍历传进来的这个数组
System.out.println("请输入arrays[" + i +"]=?");//提示语句
arrays[i] = scanner.nextInt();//给数组内元素依次赋值
}
return arrays;//返回赋值完成的数组
}
/**
* 遍历打印数组
* @param arrays
*/
static void ergodicPrintArray(int[] arrays){//传进来一个数组
for(int i = 0; i < arrays.length; i++){//遍历传进来的这个数组
System.out.println(arrays[i] + " ");//输出数组的每个元素的值
}
}
/**
* 找到数组arrays中元素值为num的下标,如果能找到就返回下标值,没找到就返回-1
* @param arrays
* @param num
* @return
*/
static int findIndex(int[] arrays,int num){//传进来一个数组,和一个整型值
for(int i = 0; i < arrays.length; i++){//遍历这个数组
if(arrays[i] == num){//将数组内下标为i的数组元素值和整型值比较,
return i;//两者值相等就返回这个数组元素值的下标i
}
}
return -1;//不满足就返回-1
}
/**
* 给数组arrays内某数字的下标位置index添加值num
* @param arrays
* @param index
* @param num
* @return
*/
//将初始数组、要插入位置的下标值、要插入的元素值传进来
static int[] arraysInsertNum(int[] arrays,int index, int num){
/*
* 判断下标值
*/
if(index == -1 || index > arrays.length){//如果下标值等于-1或者大于数组长度就指针越界
System.out.println("你输入的元素值有误");
}
/*
* 往数组添加元素
*/
int[] arraysNew = new int[arrays.length + 1];//定义一个新数组,用来存放插入元素后的数组
for(int i = 0; i < arrays.length; i++){//遍历数组
if(i < index){
arraysNew[i] = arrays[i];//插入位置之前的元素,原封不动挪到新数组里
}else {
arraysNew[i + 1] = arrays[i];
}
}
arraysNew[index] = num;
return arraysNew;
}
}
删除一个元素
public class ArraysDeleteNum{
static Scanner scanner = new Scanner(System.in);//从控制台获取数据的工具
public static void main(String[] args){
//定义一个长度为10的数组,这时还未给数组内元素进行赋值,所以这时候数组内元素的值都是默认值0
int[] arrays = new int[10];
giveNum(arrays);//调用giveNum方法,从控制台给数组内元素赋值
System.out.println("请输入你要删除的元素值");
//调用findIndex方法,获得arrays数组内某个值的下标
int index = findIndex(arrays,scanner.nextInt());
//调用arraysDeleteNum方法删除某个元素,生成新的数组
//调用ergodicPrintArray方法遍历新数组
ergodicPrintArray(arraysDeleteNum(arrays,index));
}
/*
* 从控制台给数组内元素赋值
*/
static int[] giveNum(int[] arrays){
for(int i = 0; i < arrays.length; i++){
System.out.println("请输入arrays[" + i +"]=?");
arrays[i] = scanner.nextInt();
}
return arrays;
}
/*
* 遍历打印数组
*/
static void ergodicPrintArray(int[] arrays){
for(int i = 0; i < arrays.length; i++){
System.out.println(arrays[i] + " ");
}
}
/*
*找到数组arrays中元素值为num的下标,如果能找到就返回下标值,没找到就返回-1
*/
static int findIndex(int[] arrays,int num){
for(int i = 0; i < arrays.length; i++){
if(arrays[i] == num){
return i;
}
}
return -1;
}
/*
* 删除数组arrays内,下标为index的元素
*/
static int[] arraysDeleteNum(int[] arrays, int index){
//判断下标值
if(index == -1 || index > arrays.length){
System.out.println("你输入的元素值有误");
}
//删除元素
//定义一个新数组,存放删除某个元素后的新序列
int[] arraysNew = new int[arrays.length -1];
for(int i = 0; i < arraysNew.length; i++){
if(i < index){
arraysNew[i] = arrays[i];
}else {
arraysNew[i] = arrays[i + 1];
}
}
return arraysNew;
}
}
查找数组内的某个元素
package demo;
import java.util.Scanner;
/**
* 查找数组的某个元素
* @author Amid
*
*/
public class ArrayFind {
static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
int[] arr = new int[5];
giveNum(arr);//调用方法,给数组内元素赋值
System.out.println("请输入你要查找的数字");
int index = findIndex(arr, scanner.nextInt());//调用方法,获取倒要查找数字的下标
if(index == -1) {
System.out.println("他在数组中不存在");
}else {
System.out.println("存在");
}
}
/**
* 从控制台给数组arr内元素赋值
* @param arr
*/
static int[] giveNum(int[] arr) {
for(int i = 0; i < arr.length; i++) {
System.out.println("请输入arr[" + i +"]=?");
arr[i] = scanner.nextInt();
}
return arr;
}
/**
* 找到arr数组内某元素值num对应的数组下标
* @param arr
* @param num
* @return
*/
static int findIndex(int[] arr, int num) {
for(int i = 0; i < arr.length; i++) {
if(num == arr[i]) {
return i;
}
}
return -1;
}
}
给数组中插入元素
package demo;
import java.util.Scanner;
/**
* 给数组中插入元素
* @author Amid
*
*/
public class ArraysInsertNum{
static Scanner scanner = new Scanner(System.in);//从控制台获取数据的工具
public static void main(String[] args){
//定义一个长度为10的数组,这时还未给数组内元素进行赋值,所以这时候数组内元素的值都是默认值0
int[] arrays = new int[10];
giveNum(arrays);//调用giveNum方法,从控制台给数组内元素赋值
System.out.println("请输入你要插入位置的元素值");
//调用findIndex方法,获得arrays数组内某个值的下标
int index = findIndex(arrays,scanner.nextInt());
System.out.println("请输入你要插入的元素值");
//调用arraysInsertNum方法,获得插入元素后的新数组
//调用ergodicPrintArray方法遍历打印新数组
ergodicPrintArray( arraysInsertNum(arrays, index, scanner.nextInt()));
}
/**
* 从控制台给数组内元素赋值
* @param arrays
* @return
*/
static int[] giveNum(int[] arrays){//把定义的数组传进来
for(int i = 0; i < arrays.length; i++){//遍历传进来的这个数组
System.out.println("请输入arrays[" + i +"]=?");//提示语句
arrays[i] = scanner.nextInt();//给数组内元素依次赋值
}
return arrays;//返回赋值完成的数组
}
/**
* 遍历打印数组
* @param arrays
*/
static void ergodicPrintArray(int[] arrays){//传进来一个数组
for(int i = 0; i < arrays.length; i++){//遍历传进来的这个数组
System.out.println(arrays[i] + " ");//输出数组的每个元素的值
}
}
/**
* 找到数组arrays中元素值为num的下标,如果能找到就返回下标值,没找到就返回-1
* @param arrays
* @param num
* @return
*/
static int findIndex(int[] arrays,int num){//传进来一个数组,和一个整型值
for(int i = 0; i < arrays.length; i++){//遍历这个数组
if(arrays[i] == num){//将数组内下标为i的数组元素值和整型值比较,
return i;//两者值相等就返回这个数组元素值的下标i
}
}
return -1;//不满足就返回-1
}
/**
* 给数组arrays内某数字的下标位置index添加值num
* @param arrays
* @param index
* @param num
* @return
*/
//将初始数组、要插入位置的下标值、要插入的元素值传进来
static int[] arraysInsertNum(int[] arrays,int index, int num){
/*
* 判断下标值
*/
if(index == -1 || index > arrays.length){//如果下标值等于-1或者大于数组长度就指针越界
System.out.println("你输入的元素值有误");
}
/*
* 往数组添加元素
*/
int[] arraysNew = new int[arrays.length + 1];//定义一个新数组,用来存放插入元素后的数组
for(int i = 0; i < arrays.length; i++){//遍历数组
if(i < index){
arraysNew[i] = arrays[i];//插入位置之前的元素,原封不动挪到新数组里
}else {
arraysNew[i + 1] = arrays[i];
}
}
arraysNew[index] = num;
return arraysNew;
}
}
去掉数组内重复元素
package demo;
import java.util.Arrays;
/**
* 去重,去掉数组内重复元素
* @author Amid
*
*/
public class DeleteRepeat {
public static void main(String[] args) {
int[] arr = {1,2,3,2,0,6,5,7,8,8,9};
System.out.println(Arrays.toString(arr));//打印原数组
System.out.println(Arrays.toString(deleteRepeat(arr)));//打印新数组
}
static int[] deleteRepeat(int[] arr) {
int[] newArr = new int[arr.length];
int index = 0;
for(int i = 0; i < arr.length; i++) {//原数组
boolean flag = true;
for(int j = 0; j < index ; j++) {//新数组
if(newArr[j] == arr[i]) {
flag = false;
break;
}
}
if(flag) {
newArr[index] = arr[i];
index++;
}
}
return Arrays.copyOfRange(newArr, 0, index);//截取0~index之间打印
}
}
利用快慢索引给有序数组去重
package demo;
import java.util.Arrays;
/**
* 对有序数组去重
* @author Amid
*
*/
public class QuicklyAndSlowIndexOrderSort {
public static void main(String[] args) {
int[] arrays = {2,3,2,5,5,6,6,6,7,8,8,9};
printArrays(quicklyAndSlowIndexToDeleteRepeat(arrays));
}
/**
* 遍历打印数组
*/
static void printArrays(int[] arrays) {
for(int i = 0; i < arrays.length; i++) {
System.out.print(arrays[i] + " ");
}
}
/**
* 慢索引存值,快索引探路
* 开始时,慢索引0 快索引1
* 快索引==慢索引,快索引后移一个
* 快索引!=慢索引,慢索引后移一个,将快索引指的值存进慢索引处,快索引后移一个
* 当快索引越界循环结束
*/
static int[] quicklyAndSlowIndexToDeleteRepeat(int[] arrays) {
int slowIndex = 0;
int quicklyIndex = 1;
while(quicklyIndex < arrays.length) {
if(arrays[slowIndex] != arrays[quicklyIndex]) {
slowIndex++;
arrays[slowIndex] = arrays[quicklyIndex];
}
quicklyIndex++;
}
return Arrays.copyOfRange(arrays, 0, slowIndex + 1);
}
}
反转数组
package demo;
import java.util.Scanner;
/**
* 反转数组
* @author Amid
*
*/
public class ArrayReversal {
static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
int[] arr = new int[5];
//方法一:借助新数组
arr = reverse_01(arr);
ergodicPrintArray(arr);//调用方法,遍历打印数组
//方法二:不借助新数组
reverse_02(arr);
ergodicPrintArray(arr);
}
static void reverse_02(int[] arr) {
//从外往内,两边同时交换
//1.一个指针
int length = arr.length;
for(int i = 0; i < length / 2; i++) {
int temp = arr[i];
arr[i] = arr[length - 1- i];
arr[length - 1- i] = temp;
}
//2.两个指针
// for(int i = 0, j = arr.length - 1; i < j; i++ , j--) {
// int temp = arr[i];
// arr[i] = arr[j];
// arr[j] = temp;
// }
}
static int[] reverse_01(int[] arr) {
int[] arrNew = new int[arr.length];
int length = arr.length;
for(int i = 0; i < arr.length; i++) {
arrNew[length - i - 1] = arr[i];
}
return arrNew;
}
/**
* 从控制台给数组arr内元素赋值
* @param arr
*/
static int[] giveNum(int[] arr) {
for(int i = 0; i < arr.length; i++) {
System.out.println("请输入arr[" + i +"]=?");
arr[i] = scanner.nextInt();
}
return arr;
}
/**
* 遍历打印数组arr(数组下标i循环遍历打印)
* @param arr
*/
static void ergodicPrintArray(int[] arr) {
for(int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
统计有序数组种元素重复次数
int[] arr = {1,1,1,2,2,3,3,6,6,6,7,7,8,9};
for(int i = 0; i < arr.length; ) {
int count = 0;
//方法1.用for循环
for(int j = i; j < arr.length; j++) {
if(arr[j] == arr[i]) {
count++;
}
}
//方法2.用while循环
// int j = i;
// while (j < arr.length && arr[j] == arr[i] ){
// count++;
// j++;
// }
System.out.println(arr[i] + "出现了" + count + "次");
i = i + count;
}
数组排序:
1.选择排序
找到最小元素,放置到下标为0的位置
从剩余的元素中再找到最小的,放到下标为1的位置
从剩余的元素中再找到最小的,放到下标为2的位置
......
n个元素,只需要将上面的过程重复n-1次
//升序排列
int[] array = {10,23,41,2,7,78,93};
for(int i = 0; i < array.length - 1; i++){
int index = i;//这里i就是原来的位置
//j=index+1前面排过的后面不再参与
for(int j = index + 1; j < array.length; j++){
if(array[index] > array[j]){
index = j;
}
}
//i就是原来的位置,index就是最小元素的位置
if(i != index){
int temp = array[index];
array[index] = array[i];
array[i] = temp;
}
}
//遍历打印
for(int t : array){
System.out.print(t + " ");
}
2. 冒泡排序
两两比较,将较大的向后交换
第一轮就是将最大元素交换到最后一个位置
第二轮将剩余元素中最大元素交换到了倒数第二位置
n个元素n-1轮即可
//这里的i < array.length-1 因为下标是从0开始,所以当数组中有n个元素,下标最大到n-1
//由于i+1也是下标,所以i+1最大只能是length-1,所以i最大只能到length-2
for(int i = 0; i < array.length-1; i++){
//当内层for循环一次if都没进过说明已经排好序了
boolean is = true; //true代表没进过if,false:进过
for(int j = 0; j < array.length-1-i; j++){
//这里array.length-1-i,,其中-i是为了提高效率少比基础,因为扔到后面的元素已经排好序了,不需要再进行比较
if(array[j] > array[j+1]){
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
is = false;
}
}
if(is){
break;
}
}
for(int t : array){
System.out.print(t + " ");
}
3.插入排序
将一个数据插入到有序链表中,使之仍然保持有序
static void charu(int[] arr) {
//第一个元素已经有序
for(int i = 1; i < arr.length ; i++) {//遍历的是原序列
for(int j = i; j > 0; j--) {//遍历的是有序序列
if(arr[j] < arr[j - 1]) {
int temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
}
}
数组的查找:
二分查找:(数组必须基本有序)
每次都和中间元素比较,一次可以去掉一半
/*
升序:
1.当要找的数字比中间数字大,说明再右边范围,
right不变,left变成mid+1
2.当要找的数字比中间数字小,说明在左边范围,
left不变,right变成mid-1
3.当right < left时,说明已经找完了,没找到,程序可以停止了
*/
int[] arr = {12,23,34,45,56};
int left = 0;//左边界
int right = arr.length - 1;//右边界
int key = 23;//要找的数字
int index = -1;//记录找到之后的下标,初始值不能给0,因为从数组下标从0开始,最后打印index==0,不知道有没有找到
//知道循环条件为right >= left,不知道循环次数,用while循环
while(right >= left){
//获取中间元素下标
int mid = (left + right) / 2;
//有时候二分查找的区间非常大,大到容易溢出21亿的int范围,我们确定mid的时候就不能够轻易使用:更为谨慎的是,应将式子变形为
//mid = left + (right - left) / 2
if(key == arr[mid]){
index = mid;
break;
}else if(key > arr[mid]){//进右边范围
left = mid + 1;
}else {//进左边范围
right = mid - 1;
}
}
if(index != -1){
System.out.println("找到了:" + index);
}else {
System.out.println("没找到");
}
随机数的生成
/*随机数*/
//第一种
Math.random();//在[0,1)之间随机一个数字,包含0,不包含1
[0,1) * n = [0,n)
[0,n] = Math.random() * (n+1)
int r = (int)(Math.random() * 101);//[0,100]
//[29,129]
int r = (int)(Math.random() * 101) + 29;
System.out.print(r);
//第二种
Random random = new Random();
random.nextInt(100);//获取0~100之间的随机数,不包含100