【Java】还不会数组?一文万字全搞定

前言:前面两章我们详细讲解了Java基本程序设计结构中的基本知识,,包括:一个简单的Java应用,注释,数据类型,变量与常量,运算符,字符串,输入输出,控制流,大数值。 本篇将介绍最后一环——“数组”,带领大家更全面透彻地了解Java中数组的相关知识。

目录

    • 一.数组的基本概念
    • 二.数组的声明和初始化
      • 2.1数组的声明
      • 2.2数组的初始化【重要】
    • 三.访问数组元素
      • 3.1数组下标/索引
      • 3.2 for循环访问数组元素
      • 3.3 for each循环
    • 四.命令行参数
    • 五.初始JVM的内存分布
    • 六.数组中常见的各类方法
      • 6.1数组拷贝
      • 6.2数组排序
      • 6.3数组查找
      • 6.4数组填充
      • 6.5数组比较
    • 七.多维数组【二维数组】
    • 八.不规则数组

一.数组的基本概念

数组即存储着相同类型值的序列。
从定义中我不可以得到以下结论:

1.数组是一种数据结构,是用来存储同一类型值的集合;
2.数组中存放的值连续的;
3.每个空间有自己的编号,其实位置的编号为0,即数组的下标。

举个例子:在java中,包含6个整形类型元素的数组,就相当于下图中连在一起6个车位,从下图中可以看到:
在这里插入图片描述
那么,我们如何定义,使用一个数组呢?

二.数组的声明和初始化

2.1数组的声明

俗话说:变量先声明后使用。首先我们看看如何声明一个数组。
通过以下方式我们可以声明一个Java数组,在声明数组变量的时候,需要指出数组类型和数组变量的名字:

int[] array1;//array:英文单词表示数组
double[] array2;
boolean[] array3;
//...

这时我们就成功声明了一个array数组。看到这里,一些有C语言基础的小伙伴就会有一种“熟悉的陌生人”的感受,因为C语言是这样声明一个数组的:

int arr[];//C语言实现方式

两者看上去非常相似,仅仅只是“[ ]”的位置不同,实际上,在Java中,这两种形式都可以定义声明一个数组变量。只不过,大多数Java程序员更倾向于第一种方式,因为这样可以清晰地将变量类型和变量名区分开来,显得更加有逻辑性。(相当于我创建了一个名为array的变量,变量的类型是int[ ]).

2.2数组的初始化【重要】

在Java中,数组的初始化方式相对比较灵活,接下来我们一一讲解不同的初始化方式:
方法一:直接法

//对于一中我们声明的数组我们仅仅声明了变量array,并没有将它初始化为一个真正的数组
//方法一:直接初始化法
int[] array={1,2,3,4,5}//这种方式直接指明了数组中元素的值

这种方式对于C小伙伴们是最熟悉不过的,优点是简便直接,缺点是如果数组中元素个数过多,就显得比较麻烦了。
补充:这种初始化语法中不需要使用new(后文讲解),甚至不用指定长度。最后一个值后面允许有逗号,如果你要不断为数组增加值,这很方便:

String[] names={"彭于晏”,
"陈冠希",
"刘德华”,
//...
//可以在这之后添加更多的name,这个逗号是被允许的
}

方法二:新创建法

//方法二:new int[元素个数];
int[] array=new int[100];
//等价于var array=new int[100];

new int[n]语句会创建一个长度为n的数组,一旦创建了数组,就不能再改变它的长度(不过,可以改变单个数组元素)。如果程序运行过程中需要经常扩展数组大小,就应当使用另一种数据结构——“数组列表”(array list),以后会讲解。

方法三:匿名数组法

//方法三:
int[] array=new int[]{1,2,3,4,5};

这种方式会分配一个新数组并填入大括号中提供的值。它会统计初始值个数,所以new int[]中不需要指定数组个数。

补充:在Java中,允许有长度为0的数组。如果在编写一个结果为数组的方法时,这样一个长度为0的数组就很有用。可以如下创建长度为0的数组:
new elementType[0]

new elementType[] {}
注意:长度为0的数组与null并不相同!

三.访问数组元素

3.1数组下标/索引

我们以及成功声明并初始化好了一个数组,即我们准备工作已经完成,那么如何去使用一个数组呢?这时我们就需要学会去访问数组元素。
访问数组元素就需要我们找到数组元素“下标/索引”。

array[index];//通过下标/索引找到了对应数组元素

同其它程序设计语言一样,Java数组元素下标也是从0开始的,例如我们创建一个元素个数为100的数组,那么它的下标就是从0到99(而不是1到100)。一旦创建了数组,我们就可以在数组中填入元素:

int[] arrary=new int[100];
for (int i = 0; i < 100; i++) {
      arrary[i]=i+1;
      //向数组中填入数组1到100
 }

创建一个数字数组的时候,所有元素均初始化为0。boolean数组元素会初始化为false。对象数组元素则初始化为一个特殊值null,表示这些元素还未存放任何对象。初学者可能不解i,例如:

String[] names=new String[10];

会创建一个包含10个字符串的数组,所有的字符串均为null。如果希望这个数组包含空串,必须为元素指定空串:

 for (int i = 0; i < 10; i++) {
      	names[i]="";
}

3.2 for循环访问数组元素

此外,在访问数组元素的时候如果需要向数组中添加或删除一个值,第一步就是要改变数组内容,第二步在访问新数组元素的时候我们还需要修改数组元素个数。在Java中提供了一种array.length方法可以获取数组中元素个数,再通过for循环访问数组元素,例如:

 int[] a=new int[]{12,3,46,5,5,5,2,879};
 for (int i = 0; i < a.length; i++) {
       System.out.println(a[i]);
}

最后就是一个老生常谈的bug了——数组不能越界访问!
例如:我们创建了一个100个元素的数组,并试图访问array100,就会引发如下异常:
在这里插入图片描述
即表明你访问了一个越界的数组元素,这是不被允许的。

3.3 for each循环

虽然上一篇中我们已经提到了for each循环,但是由于它在数组中是一种较为新颖的循环,我们再次在这里提及它。
for each循环是Java中一种功能很强的循环结构,可以用来依次处理数组(或者其它元素集合)中的每个元素,==而不必考虑指定下标值。==这也是它区别与普通for循环最大的不同。
其格式为下:

for(变量:集合) statement

它定义一个变量用于暂存集合中的每一个元素,并执行相应语句(或语句块)。集合的表达式必须是一个数组或者是一个实现了Iterable接口的类对象(例如ArrayList,以后会讲解)。例如:

int[] a=new int[]{1,2,3,4,5};
for(int element:a)
    System.out.println(element);
    /*1
	  2
	  3
	  4
	  5*/

打印数组a的每一个元素,一个元素占一行。
实际上,这个循环应该读作“循环a中的每一个元素”(for each element in a)这也是它名字由来。
相比于传统for循环for each循环语句显得更加简洁,更不易出错,因为你不必因为下标的起始值和终止而操心。以下是二者对比:

//二维数组 就是一个特殊的一维数组
for (int i = 0; i < array.length; i++) {
    for (int j = 0; j < array[i].length; j++) {
          System.out.print(array[i][j]+" ");
	}
          System.out.println();
}/**/

System.out.println("=====");

for(int[] tmpArray : array) {
     for(int x : tmpArray) {
           System.out.print(x+" ");
     }
     System.out.println();
}

注意:for each循环语句的循环变量会遍历数组中的每个元素,而不是下标值。

此外,如果你仅仅想打印出数组中的所有值,那么Java中有一个更加简单的方式,即利用Array类中的toString方法,调用Array.toString(a),返回一个包含数组元素的字符串,这些元素包含在中括号内,并用逗号分隔开。例如:
在这里插入图片描述
结果如下:
在这里插入图片描述
注意引入包:import java.util.Arrays;

此外,我们还可以自我实现一个myToString方法:

   public static String myToString(int[] array) {
        String ret = "[";
        for (int i = 0; i < array.length; i++) {
            ret = ret + array[i];
            if(i != array.length-1) {
                ret += ", ";
            }
        }
        ret += "]";
        return ret;
    }

四.命令行参数

前面已经看到多个使用Java数组的示例。每一个Java应用程序都有一个带String[] args参数的main方法。这个参数表明main方法将接收一个字符串数组,也就是命令行参数。例如,看一看下面这个程序:

public class Test{
	public static void main(String[] args){
		if (args[0]. equals("-h"))
			System.out. print("Hello, ");
		else if (args[0]. equals("-g"))
			System. out.print("Goodbye, ");
		// print the other command-line arguments
		for (int i = 1; i < args. length; i++)
			System.out. print(" "+ args[i]);
		System.out.println("!");
	}
}

如果使用java Test -g cruel world命令调用这个程序,args数组将会包含一下内容:args[0]=“-g” args[1]=“cruel” args[2]=“world”。这个程序就会显示下面这个信息:
在这里插入图片描述

五.初始JVM的内存分布

在深入了解数组的使用之前,我们现要了解一下JVM的内存分布,可是我们为什么要了解这个东西呢?
我们知道,Java的程序是跑在虚拟机(即JVM)上,我们要想理解数组这一引用类型是如何引用变量的,就必须了解其它JVM上的内存是如何分配的。
首先,JVM对所使用的内存按照功能的不同进行了划分:
在这里插入图片描述
解释一下里面的各个部分:

  • 程序计数器 (PC Register): 只是一个很小的空间, 保存下一条执行的指令的地址
  • 虚拟机栈(JVM Stack): 与方法调用相关的一些信息,每个方法在执行时,都会先创建一个栈帧,栈帧中包含有:局部变量表、操作数栈、动态链接、返回地址以及其他的一些信息,保存的都是与方法执行时相关的一些信息。比如:局部变量。当方法运行结束后,栈帧就被销毁了,即栈帧中保存的数据也被销毁了。
  • 本地方法栈(Native Method Stack): 本地方法栈与虚拟机栈的作用类似. 只不过保存的内容是Native方法的局部变量. 在有些版本的 JVM 实现中(例如HotSpot), 本地方法栈和虚拟机栈是一起的
  • 堆(Heap): JVM所管理的最大内存区域. 使用 new 创建的对象都是在堆上保存 (例如前面的 new int[]{1, 2, 3,4,5} ),堆是随着程序开始运行时而创建,随着程序的退出而销毁,堆中的数据只要还有在使用,就不会被销
    毁。
  • 方法区(Method Area): 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据. 方法编译出的的字节码就是保存在这个区域

简单解释一下这里为什么会出现两个栈区:我们知道JVM底层是由C/C++实现的,而本地方法栈中就包含了一些由C/C++程序实现的方法。而虚拟机栈才是我们平时所说的栈区。
现在我们只简单关心堆 和 虚拟机栈这两块空间,后序JVM中还会更详细介绍。

六.数组中常见的各类方法

6.1数组拷贝

在Java中,允许将一个数组变量拷贝到另一个数组变量中去,这时,两个变量将引用同一个数组

        int[] smallPrimes=new int[10]; 
        int[] luckyNumbers=new int[10];
        luckyNumbers[5]=12;
        luckyNumbers=smallPrimes;//smallPrimes[5]==12

在这里插入图片描述

正常来说我们自己是可以很轻松实现一个数组拷贝的方法的:

   public static int[] copyArray(int[] array) {
        int[] copy = new int[array.length];
        for (int i = 0; i < array.length; i++) {
            copy[i] = array[i];
        }
        return copy;
    }

但Java中提供了更便捷的Arrays类的copyOf方法:

luckyNumbers=Arrays.copyOf(luckyNumbers,luckyNumbers.length);
//第一个参数是要拷贝的原始数组
//第二个参数是新数组的长度

这个方法通常用来增加数组大小

luckyNumbers=Arrays.copyOf(luckyNumbers,2*luckyNumbers.length);

如果数组元素是数值型,那么额外的元素将被赋值为0;如果数组元素是布尔型,则将赋值为false。相反,如果长度小于原始数组的长度,则只拷贝前面的值。
此外,还有类似的Arrays类的copyOfRange方法:

public static void main(String[] args) {
    int[] array = new int[] { 1,2,3,4 };
    int[] ret = Arrays.copyOfRange(array,2,4);
    //第一个参数:要拷贝的原始数组
    //第二个参数from:表示要拷贝的起始位置
    //第三个参数to:表示要拷贝的终止位置
    System.out.println(Arrays.toString(ret));//[3,4]
}

Java数组与堆栈上的C++数组有很大的不同,但基本上与在**堆(heap)**上分配的数组指针一样,也就是说:
int[] a=new int[100];//Java
不同于
int[] a[100];//C++
而等同于
int* a=new int[100];//C++
表明Java中数组变量存储的本质上是一个地址,通过这个地址“引用”到堆区上的目标对象。
同时,Java中的[ ]运算符被预定义为会完成 越界检查,而且没有指针运算,即不能通过a+1得到数组中的下一个元素。

6.2数组排序

我们之前对数组常用的排序是冒泡排序,这里我们再次回顾一下:

public static void bubbleSort(int[] array){
        //i表示循环的趟数
        for (int i = 0; i < array.length-1; i++) {
            boolean flag=false;
            for (int j = 0; j < array.length-1-i; j++) {
                //从小到大排序
                if(array[j]>array[j+1]) {
                    int tempArray = array[j];
                    array[j]=array[j+1];
                    array[j+1]=tempArray;
                    flag=true;
                }
            }
            if(flag==false)
                return;
        }
    }
    public static void main(String[] args) {
            int[] a=new int[]{1,3,2,6,0,9};
            bubbleSort(a);
        for (int b:a) {
            System.out.print(b+" ");
        }
        //0 1 2 3 6 9
    }

要想对数值型数组进行排序,我们还可以使用Java中Arrays类的sort方法:

int[] a=new int[10000];
Arrays.sort(a);

这个方法使用了优化的快速排序算法。快速排序算法对于大多数数据集合来说都是效率比较高的。
接下来,我们通过一个经典案例练习一下——“抽彩游戏”:

问题描述:
抽彩是从多个数字中随机抽取几个不重复的值,进行排序输出且判断是否中奖。若中奖则输出中奖次数,若未中奖则给出提示。
在这里插入图片描述

示例代码如下:

import java.util.Arrays;
import java.util.Scanner;

public class LotteryDrawing {
    public static void main(String[] args) {
        int count = 0;
        //定义一个计量数,计算中奖了几次
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入您要抽取数字的最高数:");
        int n = sc.nextInt();
        //设定一个n存放最高位数值
        int n1 = n;
        //定义了一个n1与n的数值相同
        System.out.println("请输入您要抽取几个数字(1~"+n+"):");
        int k = sc.nextInt();
        //设定了抽取数
        if(k>n){
            System.out.println("对不起,您输入的数字不符合规范!");
            //若此时抽取数比最高数要高则报错
        }else{
            int[] numbers1 = new int[n];
            int[] numbers2 = new int[n1];
            //定义了两个数组,其长度分别与n和n1相同
            for (int i = 0; i < numbers1.length; i++) {
                numbers1[i] = i+1;
                //对数组numbers进行从1~n的赋值;
            }
            for (int i = 0; i < numbers2.length; i++) {
                numbers2[i] = i+1;
                //对数组numbers2进行从1~n1的赋值;
            }
            int[] result = new int[k];//抽取结果
            //定义了result数组使其长度等于抽取数k
            for (int i = 0; i < result.length; i++) {
                int r =(int) (Math.random()*n);
                //Math.random()*n会得到一个0到n-1之间的随机数,左闭右开!
                //抽取随机数的本质是抽取随机下标
                result[i] = numbers1[r];
                //选择随机数numbers[r]赋值给result[i]
                numbers1[r] = numbers1[n - 1];
                n--;
                //这里确保了不会再次抽取到同一个值
            }
            int[] winning = new int[k];//中奖结果
            for (int i = 0; i < winning.length; i++) {
                int w = (int) (Math.random()*n);
                winning[i] = numbers2[w];
                numbers2[w] = numbers2[n1 - 1];
                n1--;
            }
            Arrays.sort(result);
            //对数组进行排序
            System.out.println("抽取完成,您抽取的数为:");
            for(int r :result){
                System.out.print(r+" ");
            }
            //使用foreach循环对数组进行遍历
            System.out.println("");
            //换行
            Arrays.sort(winning);
            System.out.println("中奖数为:");
            for (int w:winning){
                System.out.print(w+" ");
            }
            for (int x = 0; x < result.length; x++) {
                for (int y = 0; y < winning.length; y++) {
                    if(result[x] == winning[y]){
                        count++;
                    }
                }
            }
            //使用两个for循环且利用if语句对数组的值进行判断
            //若有相同值则count计数值自增
            System.out.println();
            if(count == 0){
                System.out.println("对不起,您未中奖,请再接再厉!");
            }else{
                System.out.println("恭喜您,您中奖了"+count+"次");
            }
        }

    }
}

这个案例综合了数组排序的相关内容,仔细研读定会有所收获。

6.3数组查找

在数组使用中,有时我们需要在数组中找到目标元素,这时候我们就需要了解一些数组查找的方法:
方法一:直接暴力查找

  public static int findNum(int[] array,int key) {
        for (int i = 0; i < array.length; i++) {
            if(array[i] == key) {
                return i;
            }
        }
        return -1;
        //因为直接法是挨个查找,所以效率很低
    }

这种方式是最直接最简单但效率最为低下的方式,仅限数组大小较小时使用。
方法一:二分查找

 public static int binarySearch(int[] array,int key) {
        int left = 0;
        int right = array.length-1;
        while (left <= right) {
            int mid = (left+right) / 2;
            if(array[mid] == key) {
                return mid;
            }else if(array[mid] > key) {
                right = mid - 1;
            }else {
                left = mid + 1;
            }
        }
        return -1;
    }

这个方法相比于方法一效率还是提升了不少的。
对于数组查找,当然Java也提供了相应的方法Arrays类的binarySearch方法:

Arrays.binarySearch(int[] a,key);

具体使用方法就不必多说了,直接用!
Java当然不止提供了这一种排序方法,借助Java帮助手册我们可以自行查询相应方法和参数,结合实际情况和对应具体功能合理选择。

6.4数组填充

有时我们定义完数组后想要对其初始化一般是用for循环解决。
而Java中提供了Arrays类的fill方法:
功能:对数组内容进行指定填充。

public static void main(String[] args) {
            int[] array = new int[10];
            Arrays.fill(array,5);
            Arrays.fill(array,4,6,10);
            System.out.println(Arrays.toString(array));
            //[5, 5, 5, 5, 10, 10, 5, 5, 5, 5]
}

6.5数组比较

在上一篇中我们提到了数组之间的比较一定不能使用“ ==”比较 ,如果相等仅仅只能表明两个数组存储在相同的位置,而不能表示两个数组存储的内容是完全等同的。
而Java中提供的Arrays类的equals方法实现了数组的比较:

public static void main(String[] args) {
    int[] arr1 = new int[] { 5,4,3,2,1 };
    int[] arr2 = new int[] { 1,2,3,4,5 };
    int[] arr3 = new int[] { 1,2,3,4,5};
    System.out.println(Arrays.equals(arr1, arr2));//false
    System.out.println(Arrays.equals(arr2, arr3));//true
}

七.多维数组【二维数组】

多维数组中我们主要围绕最常见的二维数组展开讨论,这里我们就不详细一一解释了,因为它和一维数组大同小异:

      //二维数组的声明和初始化
       //以Int为例,
       //法一:静态初始化
       int[][] list={{123}{4,5,6},{7,8,9}};
       //法二:动态初始化
       int[][] list=new int[5][10];
       //法三:列数不确定
       int[][] list=new int[5][];
       //此时所有的一维数组都没有开辟内存空间,它们的地址都为 null;

这里举一个案例,观察一下二维数组在JVM中的内存分布:
在这里插入图片描述
实际上,二维数组的本质就是一个存储着一维数组的数组,它的各个一维数组的内存大小可以相同,也可以不相同。(不规则数组)
对于二维数组的访问我们跟一维数组类似,也有两种实现方式:

int[][] list={{1,2,3},{4,5,6},{7,8,9}};
//法一:
 for (int i = 0; i < list.length; i++) {
     for (int j = 0; j < list[0].length; j++) {
         System.out.print(list[i][j]+" ");
     }
         System.out.println();
}
     System.out.println("==================");
//法二:
for (int[] x :list) {
      for (int y:x) {
         System.out.print(y+" ");
      }
         System.out.println();
}
/*
1 2 3 
4 5 6 
7 8 9 
==================
1 2 3 
4 5 6 
7 8 9 */
   }

八.不规则数组

刚才我们提及了二维数组可以省略行初始化,即:

int[][] list=new int[5][];

为什么可以这样呢?我们知道,二维数组本质上是一个存储着一维数组的数组。列数的不确定可以使我们对数组进行更加灵活的处理,即可以方便地构造一个“不规则”数组,即数组的每一行都有不同的长度
下面我们通过一个杨辉三角案例具体了解一下不规则数组的实现:

问题描述:
在这里插入图片描述

示例代码如下:

    public static void main(String[] args) {
            int[][] a = new int[10][];

            for (int i = 0; i < a.length; i++) {
                // 给二维数组中每一个一维数组在堆上开辟内存空间
                a[i] = new int[i + 1];
                // 遍历每一个一维数组,赋值
                for (int j = 0; j < a[i].length; j++) {
                    // 每一行的第一个元素和最后一个元素都是1
                    if (j == 0 || j == a[i].length - 1) {
                        a[i][j] = 1;
                    } else {
                        // 每一行非第一个元素和最后一个元素的值 = 上一行的同一列 + 上一行的上一列
                        a[i][j] = a[i - 1][j] + a[i - 1][j - 1];
                    }
                }
            }

            // 输出杨辉三角
            for (int i = 0; i < a.length; i++) {
                for (int k = 0; k < a[i].length; k++) {
                    System.out.print(a[i][k] + "\t");
                }
                System.out.println();
            }
}

总结:本篇详细讲解了Java中数组的使用,我们不能发现,其实许多功能和方法Java中都有相应的封装好的类方法供你使用,一方面我们要去了解怎么实现,但更重要的是要学会去自行检索各类方法然后快速上手使用。本篇到此结束,看到这里实属不易,您的支持与鼓励是我前进最大的动力!也希望屏幕前的你能有所收获。

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

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

相关文章

冯喜运:5.10黄金反弹受阻,原油EIA库存激增引发市场情绪

【黄金消息面分析】&#xff1a;据最新市场数据显示&#xff0c;现货黄金在周四欧市早盘经历了显著下滑&#xff0c;价格一度跌破2310美元/盎司的关口&#xff0c;日内高点回落达10美元&#xff0c;截至发稿&#xff0c;黄金小幅反弹&#xff0c;交投于2312美元/盎司附近。此番…

网络新手如何上手水牛社软件?我的建议与看法

水牛社是一款专为电脑用户设计的软件&#xff0c;拥有明确的著作权&#xff0c;其核心功能在于发布和整合各类网络活动任务资源、教程等&#xff0c;内容多元且不设固定分类。其靠谱程度取决于你对软件的了解程度和个人需求的适配性。 软件内部包含五个主要栏目&#xff0c;大…

mysql: docker 异常 - mbind: Operation not permitted

mbind: Operation not permitted 前言&#xff1a;正文:结论 &#xff1a; 前言&#xff1a; 用数据库处理平台问题今天报错&#xff0c;mbind: Operation not permitted。 mbind 不允许操作&#xff0c;一头雾水这是什么意思。 网上找了很多资料大概意思是&#xff1a; 这个错…

SpringBoot中使用RocketMQ实现事务消息来保证分布式事务的一致性(有代码)

前言 分布式事务是分布式系统中非常常见的问题。是非常必要钱常见的。实现的方式也是多种多样。今天这个视频主要来分享一下RocketMQ实现事务消息来保证分布式事务的一致性。不知道大家使用过这种方式没有。这种分布式事务的原理其实和本地消息表一样。 本地消息表实现分布式…

1.基于python的单细胞数据预处理-质量控制

目录 质量控制过滤低质量细胞的指南双细胞过滤手动过滤低质量读数细胞自动过滤低质量读数细胞环境RNA校正 参考&#xff1a; [1] https://github.com/Starlitnightly/single_cell_tutorial [2] https://github.com/theislab/single-cell-best-practices 质量控制 原始的单细胞…

模拟实现链表的功能

1.什么是链表&#xff1f; 链表是一种物理存储结构上非连续存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的引用链接次序实现的 。 实际中链表的结构非常多样&#xff0c;以下情况组合起来就有8种链表结构&#xff1a; 单向或者双向 带头或者不带头 …

猫头虎分享已解决Bug || Node.js安装失败Error: unable to connect to https://nodejs.org/猫头虎

猫头虎分享已解决Bug || Node.js安装失败Error: unable to connect to https://nodejs.org/猫头虎 博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — …

活动回顾 |观测云 AI Agent 探索实践

亚马逊云科技“构建全球化软件和互联网新生态——ISV 行业”论坛上&#xff0c;观测云产品架构师刘锐发表了题为“AI Agent 可观测性探索与实践”的主题演讲&#xff0c;不仅展示了观测云在人工智能领域的前沿技术&#xff0c;更强调了在日益复杂的系统环境中&#xff0c;实现有…

autoware.universe 使用之Rosbag replay simulation放包仿真

本文将按照官方文档&#xff0c;通过播放rosbag录制包进行可视化模拟&#xff0c;中间也报了很多错误&#xff0c;特此记录下来&#xff0c;以免后续踩坑。 电脑配置如下&#xff1a;    ubuntu20.04    cuda: cuda-11.6    nvidia-driver 535    ros2: foxy 关于auto…

「MDN web 入门」学习笔记

目录 写在前面 1. MDN 简介 1.1 MDN 的主要特点 1.2 MDN 的主要功能 1.3 MDN 网页开发的指南 2. 安装基础软件 2.1 专业人士工具 2.2 初学者基本工具 3. 设计网站外观 3.1 计划 3.2 绘制草图 3.3 选定素材 3.4 文本 3.5 主题颜色 3.6 图像 3.7 字体 4. 处理文…

Redis(无中心化集群搭建)

文章目录 1.无中心化集群1.基本介绍2.集群说明 2.基本环境搭建1.部署规划&#xff08;6台服务器&#xff09;2.首先删除上次的rdb和aof文件&#xff08;对之前的三台服务器都操作&#xff09;1.首先分别登录命令行&#xff0c;关闭redis2.清除/root/下的rdb和aof文件3.把上次的…

认识卷积神经网络

我们现在开始了解卷积神经网络&#xff0c;卷积神经网络是深度学习在计算机视觉领域的突破性成果&#xff0c;在计算机视觉领域&#xff0c;往往我们输入的图像都很大&#xff0c;使用全连接网络的话&#xff0c;计算的代价较高&#xff0c;图像也很难保留原有的特征&#xff0…

oracle 数据库找到UDUMP的文件名称

oracle 数据库找到UDUMP的文件名称 select p.value||\||i.instance_name||_ora_||spid||.trc as "trace_file_name" from v$parameter p ,v$process pro, v$session s, (select sid from v$mystat where rownum1) m, v$instance i where lower(p.name)user_dump_…

Java_File

介绍&#xff1a; File对象表示路径&#xff0c;可以是文件&#xff0c;也可以是文件夹。这个路径可以是存在的&#xff0c;也可以是不存在的&#xff0c;带盘符的路径是绝对路径&#xff0c;不带盘符的路径是相对路径&#xff0c;相对路径默认到当前项目下去找 构造方法&…

英伟达推出视觉语言模型:VILA

NVIDIA和MIT的研究人员推出了一种新的视觉语言模型(VLM)预训练框架&#xff0c;名为VILA。这个框架旨在通过有效的嵌入对齐和动态神经网络架构&#xff0c;改进语言模型的视觉和文本的学习能力。VILA通过在大规模数据集如Coy0-700m上进行预训练&#xff0c;采用基于LLaVA模型的…

三.Django--ORM(操作数据库)

目录 1 什么是ORM 1.1 ORM优势 1.2ORM 劣势 1.3 ORM与数据库的关系 2 ORM 2.1 作用 2.2 连接数据库 2.3 表操作--设置字段 2.4 数据库的迁移 写路由增删改查操作 项目里的urls.py: app里的views.py: 注意点: 1 什么是ORM ORM中文---对象-关系映射 在MTV,MVC设计…

2024面试自动化测试面试题【含答案】

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

若依框架dialog弹窗取消点击空白出关闭

如果想全局取消的话就找到main.js在里面加上下面的一行代码&#xff0c;添加完成之后记得清楚浏览器缓存重新加载js文件。 Element.Dialog.props.closeOnClickModal.default false;如果想指定某个弹窗取消点击空白处关闭&#xff0c;那么就找到那个弹窗加上。添加完毕之后刷新…

扩散模型~

推荐&#xff1a;write_own_pipeline.ipynb - Colab (google.com) 基本管道 一直显示NVIDIA有问题&#xff0c;所以就把.to("cuda")去掉了&#xff0c;使用Colab运行的&#xff0c;代码如下&#xff1a; from diffusers import DDPMPipelineddpm DDPMPipeline.fr…

哈希题目总结

以下列举了可以用哈希方法&#xff08;包括但不限于用HashMap和HashSet&#xff09;的题目&#xff0c;实质上是把东西丢给这些数据结构去维护。请注意有些题目中用哈希是最优解&#xff0c;有些题目中不是最优解&#xff0c;可以自行探索其时间复杂度和空间复杂度的区别&#…
最新文章