目录
数组
1.Java中数组是一种引用数据类型,不属于基本数据类型。数组的父类是object。
2.数组实际上是一个容器,可以容纳多个元素。数组是数据的集合,是集合中最简单的一种类型。
3.数组可以存储基本数据类型数据,也可以存储引用数据类型数据,但是在数组中存储引用数据类型时存储的是对象的地址,而不是直接存储对象。
4.数组对象在堆内存中,因为数组是引用数据类型。
5.数组一旦创建,数组长度不可变。
6.所有数组对象都要length属性(Java自带的)
7.数组中元素的地址是连续的,数组其实是一种简单的数据结构
8.数组都是拿首个元素的内存地址作为整个数组对象的内存地址。
9.int[]与person[]是一种数据类型只不过是引用数据类型,与int,char相似。Array1,Array2是变量名。
10.数组的优点与缺点!
优点:查询/查找/检索某个下标的元素的效率极高,可以是查询速度最高。
为什么查找速度高?
第一:第一个元素的内存地址在空间存储上是连续的。
第二:每个元素类型都相同,所占内存空间大小一样。
第三:知道第一个元素的内存地址,知道每一个元素占用内存空间的大小,又知道下标,所以通过一个数学表达式就可以算出某个下标元素的内存地址,直接通过内存地址定位元素,所以数组的检索效率最高。
在有一百个元素的数组中和在有一百万元素的数组中,检索/查找元素的效率都是一样的因为数组找数据不是一个一个找,而是通过数学表达式计算出来(算出一个内存地址,直接定位的)。
缺点:第一:由于为了保证数组中每个元素的内存地址连续,所以在数组上随机删除或者插入元素的时候,效率低,因为随机插入或者删除元素会涉及到后面元素统一向前或者向后位移的操作。
第二:无法存储大数据量的数据,因为很难开辟很大的一片连续的存储空间。很多数据空间都是零星分布。
链表的优点:
由于链表上的元素在空间存储上内存地址不连续。
所以随机增删元素的时候不会有大量元素位移,因此效率高。
在以后的开发中,如果遇到随机增删集合中元素的业务比较多时,建议使用linkedlist
链表缺点:
不能通过数学表达式计算被查找的内存地址,每一次查找都是从头开始,节点开始遍历,直到找到为止,所以linkedlist集合检索/查找的效率低。
11.数组在内存中是一个什么样的图形?
一维数组
1.一维数组的定义
格式:int[] Array1; double[] Array1; boolean[] Array1; String[] Array1; object[] Array;
2.怎么初始化一个一维数组?
包括两种方式:静态初始化一维数组,动态初始化一维数组。
静态初始化一维数组格式:java风格:int[] Array = {100,200,300};
c++风格 : int Array[] = {100,200,300}
动态初始化一维数组格式:int[] Array = new int[5];没有初始化时,每个元素默认是0。
String Array = new String[5];没有初始化时,每个元素默认是null。
Array是一个数组对象。
3.对一维数组的访问及遍历以及引用数据类型数组的初始化
public class Test{
public static void main(String[] args) {
//静态初始化数组
int[] Array01 = {100,3200,300,55,1,5};
//所有的数组对象都有length属性
System.out.println("数组中元素的长度:" + Array01.length);
//每个数组元素都有下标
//通过下标对数组中的元素进行存和取
System.out.println("数组的第一个元素:" + Array01[0]);
System.out.println("数组中最后的元素:" + Array01[Array01.length - 1]);
//一维数组的遍历
for(int i = 0; i < Array01.length; i++){
System.out.println(Array01[i]);
}
Object[] Array02 = new Object[3];
for (int i = 0; i < Array02.length; i++){
System.out.println(Array02[i]);
}
//引用数据类型数组初始化
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
//Object[] Array03 = {o1, o2, o3};
Object[] Array03 = {new Object(), new Object(), new Object()};
for (int i = 0; i < Array03.length; i++){
System.out.println(Array03[i]);
}
}
}
数据类型 | 默认值 |
byte | 0 |
short | 0 |
int | 0 |
long | 0L |
float | 0F |
double | 0.0 |
boolean | false |
char | \u0000 |
引用数据类型(String,数组) | null |
4.方法的参数是数组
public class Test{
public static void main(String[] args) {
int [] Array = new int[11];
Test.printlnArray(Array);
System.out.println("-----------------------------------------------------------------------------------------------------------");
String[] args = new String[11];
Test.printlnArray(args);
}
public static void printlnArray(int[] Array) {
for (int i = 0; i < Array.length; i++) {
System.out.println(Array[i]);
}
public static void printlnArray(String[] args){
for (int i = 0; i < args.length; i++) {
System.out.println(args[i]);
}
}
}
}
5.main方法的参数为什么是String数组解析
谁调用main方法?mian方法的String[] args参数有什么用?
jvm调用main方法时候会自动传一个数组对象过来,都是数组中没有任何数据相当于 String[] args = {}或者String[] args = new String[0]。
作用:其实这个args这个数组对象是留给用户的,用户可以在控制台上输入参数或者在ideal中的run下的edit configuration下的program arguments下输入参数,这个参数会自动转换成数组。
for example:控制台: java Test abc def xyz ideal:abc def xyz
那么这个时候JVM会自动将abc def xyz通过空格的方式进行分离,分离完成之后,自动存放到String类型数组中变成数组{"abc","def",","xyz"}。所以main方法中参数数组args主要用来接收用户输入参数。
public class Test{
public static void main(String[] args) {
//Jvm默认传递过来的这个数组对象的长度?默认0
//通过测试得出:JVM传过来的args不是null,因为如果是null,args.length就会引发空指针异常。
System.out.println(args.length);
}
}
args数组作用的例子:
模拟一个系统,假设这个系统要使用,必须输入账号密码才能使用。
public class Test{
//用户名和密码输入到String[] args数组中。
public static void main(String[] args) {
if(args.length != 2){
System.out.println("使用该系统时请输入程序参数,参数包括用户名和密码");
return;
}
//程序执行到此处说明用户提供了用户名和密码。
//接下来你应该判断用户名和密码是否正确。
//取出用户名和密码
String username = args[0];
String password = args[1];
//当用户名时admin,密码是123的时候表示登录成功。其他表示登录失败。
/*
if (username.equals("admin") && password.equals("123")){
System.out.println("欢迎登录成功");
}
else {
System.out.println("验证失败,用户名错误或者密码错误");
}
*/
//为了避免空指针异常,建议代码应该把admin和123写在前面。
if ("admin".equals(username) && "123".equals(password)){
System.out.println("欢迎登录成功");
}else{
System.out.println("验证失败,用户名错误或者密码错误");
}
}
}
6.一维数组的深入:数组中存储的类型是引用数据类型。
public class Test01 {
public static void main(String[] args) {
//对Animal数组进行遍历
Animal a1 = new Animal();
Animal a2 = new Animal();
Animal a3 = new Animal();
Animal[] animals = {a1, a2, a3};
for (int i = 0; i < animals.length; i++) {
//测试数组多态
animals[i].move();
animals[i] = new cat();
animals[i].move();
}
//创建一个Animal类型数组,存储bird,cat
Animal[] animals1 = {new cat(), new bird()};
for (int i = 0; i < animals1.length; i++){
System.out.println(animals1[i]);
//cat c = animals1[i];不兼容的类型: Animal无法转换为cat
//cat c = (cat)animals1[i];//class bird cannot be cast to class cat
//cat与bird无关系,不可转换,因此要区分是cat还是bird
if (animals1[i] instanceof cat){
cat c = (cat)animals1[i];
}else if (animals1[i] instanceof bird){
bird b =(bird)animals1[i];
}
}
}
}
class Animal{
public void move(){
System.out.println("Animal move..");
}
}
class cat extends Animal{
public void move(){
System.out.println("猫在走猫步");
}
public void catchmouse(){
System.out.println("猫抓老鼠");
}
}
class bird extends Animal{
public void move(){
System.out.println("bird fly");
}
public void sing(){
System.out.println("鸟儿在唱歌");
}
}
7.数组的扩容
在Java中一旦数组一旦确定建立长度就不可变,那么数组满了怎么办?
那就数组扩容,数组扩容就是首先建一个大容量数组,然后把小数组拷贝到大数组之中。
结论:数组扩容效率低,因为涉及拷贝的数据,尽量预估好数组的大小减少数组的扩容,提高效率。
代码示例如下:
public class Test01 {
public static void main(String[] args) {
//java数组中是怎么进行拷贝的呢?用System类下面的静态arraycopy方法是用来数组扩容的
//基本数据类型拷贝
int[] i = {1,1,1,111,1,1,22};
int[] q = new int[15];
System.arraycopy(i,0,q,0,i.length);
for (int i1 = 0; i1 < q.length; i1++){
System.out.println(q[i1]);
}
//引用数据类型拷贝
String[] str = {"hello", "world"};
String[] strings = new String[5];
System.arraycopy(str, 0, strings, 0, str.length );
for (int i1 = 0; i1 < strings.length; i1++){
System.out.println(strings[i1]);
}
}
}
二维数组
1.定义
二维数组其实是一个特殊的一维数组,特殊在这个二维数组当中的每一个元素是一个一维数组。
a[3][4]是代表有三个一维数组,每个一维数组有四个元素,a代表二维数组,a[1]代表第二个一维数组,a[1][3]代表第二个一维数组中的第四个数据。
a.length是3,a[0].length是4,因为二维数组相当于是很多个一维数组,a是二维数组,a.length是二维数组的长度也就是在二维数组中一维数组的个数。a[0]是二维数组中的第一个一维数组,因此a[0].length就是二维数组中一维数组的长度。
三维数组其实是一个特殊的二维数组,特殊在这个三维数组当中每一个元素是一个二维数组。
2.二维数组初始化
二维数组静态初始化:
int[][] i = { {100,1,2},
{1,2,3},
{1,2,5}
};
二维数组初始化:int[][] i = new int[5][8];
3.二维数组的length属性
public class Test01 {
public static void main(String[] args) {
int[] array = {100, 200, 300};
System.out.println(array.length);
System.out.println("================================================");
int[][] array1 = {
{200,100,300},
{30,20,40,50,60},
{6,7,8,9,1},
{0}
};
System.out.println(array1.length);//4
System.out.println(array1[0].length);//3
System.out.println(array1[1].length);//5
System.out.println(array1[2].length);//5
System.out.println(array1[3].length);//1
}
}
4.方法的参数是二维数组
public class Test01 {
public static void main(String[] args) {
int[][] a = new int[3][4];
for (int i = 0; i < a.length; i++){
for (int j = 0;j < a[i].length;j++){
System.out.print(a[i][j] + " ");
}
System.out.println();
}
System.out.println();
printArray(a);
}
public static void printArray(int[][] b){
for (int i = 0; i < b.length; i++){
for (int j = 0;j < b[i].length;j++){
System.out.print(b[i][j] + " ");
}
System.out.println();
}
}
}
数组的实际应用
1.编写程序,使用一维数组,模拟栈数据结构。
1.1 这个栈中可以存储任何引用类型的数据。
1.2 在这个栈中提供push方法进行压栈。(栈满要提示)
1.3在栈中提供pop方法模拟弹栈。(栈空了要提示)
1.4编写测试程序,new栈对象,调用push,pop模拟压栈弹栈。
public class Test{
//用户名和密码输入到String[] args数组中。
public static void main(String[] args) {
Mystack m = new Mystack();
m.push(new Object());
m.pop();
}
}
class Mystack{
private Object[] elements;
private int index = -1;
public void push(Object obj){
if(this.index >= this.elements.length - 1){
System.out.println("压栈失败,栈已满");
return;
}
this.index++;
this.elements[this.index] = obj;
System.out.println(obj + "压栈成功");
}
public void pop(){
if(this.index <= -1){
System.out.println("弹栈失败,栈已空");
return;
}
System.out.println(this.elements[index] + "弹栈成功");
this.elements[this.index] =null;
this.index--;
}
public Object[] getElements() {
return elements;
}
public void setElements(Object[] elements) {
this.elements = elements;
}
public Mystack(){
this.elements = new Object[10];
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
2.编写程序为某个酒店模拟酒店管理系统,模拟订房,退房,打印房间状态等功能
2.1 该系统用户为酒店前台。
2.2 酒店使用二维数组来模拟“Room[][] rooms”
2.3 酒店中每一个房间应该是一个java对象
2.4 每一个房间应该有编号属性,房间类型属性,房间是否空闲属性。y
2.5系统应该对外提供的功能:
可以预定房间:用户输入房间编号订房。
可以退房:用户输入房间编号,退房。
可以查看所有房间状态:用户输入某个指令可以查看所有房间的状态。
数组常见的工具类(算法)
排序算法:冒泡排序算法,选择排序算法
查找算法:二分法查找
算法在Java中不需要精通,因为java中已经封装好了,要排序就调用方法就行。Java中提供了一个数组工具类Arrays。