Java中数组的深入学习

数组深入学习

标签(空格分隔): 数组


概念

1)数组是一种效率最高的存储结构和随机访问对象引用序列的方式;ArrayList通过将旧实例中的所有引用移到新实例中,从而实现更多空间的自动分配,但需要开销,所以ArrayList的效率不如数组
2)数组标识符是一个引用,指向在堆中创建的一个对象,数组保存的只是对象的引用(对于非对象,如基本数据类型,数组保存的是基本数据类型的值)
3)数组的容量大小固定,所以强调的是性能而不是灵活性
##length和元素个数
1)成员length是数组的一部分,表示数组能容纳的元素个数
2)新生成一个数组【对象】时,其中所有的引用都被初始化为null,所以检查其中的引用是否为null,就可以得到数组某个位置是否有对象,以及数组中元素的个数

int count = 0;
for(int i = 0; i < arr.length; i++){
	if(arr[i] != null)
		count++;
}
System.out.println("count : " + count);

3)生成的数组是数值型时,数组中的元素会被自动初始化为0(double 0.0);如果是字符型(char),则初始化为(char)O;如果是布尔型,则被初始化为false;

double []drr = new double[5];
System.out.println(Arrays.toString(drr));
char []crr = new char[5];
System.out.println(Arrays.toString(crr));
output:[0.0, 0.0, 0.0, 0.0, 0.0]
[o,o,o,o,o]

返回数组

java中,你无须为数组负责,在函数中使用完数组后,垃圾回收器会清理掉它

public String[] Function(){
	String str = "java-c++-php-mysql-html";
	String []arr = str.split("[-]");
	return arr;
}

多维数组

打印多维数组可用Arrays.deepToString()方法,该方法可以将多维数组转换为多个String

Arrays.deepToString(Object []arr):返回String
int [][]table = {
		{1,4,6},
		{5,2,9},
		{8,0,3}
};
System.out.println(Arrays.deepToString(table));
output:[[1, 4, 6], [5, 2, 9], [8, 0, 3]]
Object[]d = {2,9,3,1,6};

泛型与数组

通常,编译器不允许实例化泛型数组(即无法直接创建泛型数组的实例对象),但可以创建对泛型数组的引用;因为数组必须知道它所持有的确切类型,以强制保证类型安全。
T []arr = new T[length]; 是非法的
解决方法是先创建Object类数组,再将其进行转型

class test<T>{
	T []array;
	public test(){
//		this.array = new T[5];   is error!
		Object []obj = new Object[5];
		this.array = (T[])obj;
	//  this.array = (T[])(new Object[5]);
	}
}

Arrays.fill()

fill()方法,只能用同一个值填充各个位置;而对于对象,就是复制同一个引用进行填充

String []str = new String[8];
Arrays.fill(str, "JAVA");
System.out.println(Arrays.toString(str));
//将strat到end-1位置的元素用新的元素填充
Arrays.fill(str, 4,7,"MySQL");
System.out.println(Arrays.toString(str));
output:
[JAVA, JAVA, JAVA, JAVA, JAVA, JAVA, JAVA, JAVA]
[JAVA, JAVA, JAVA, JAVA, MySQL, MySQL, MySQL, JAVA]

复制数组

Java标准类库提供了static方法System.arraycopy();
该方法复制数组比for循环复制要快很多
System.arraycopy(src, srcPos, dest, destPos, length);
将源数组src中的元素复制到目的数组dest中,
srcPos是源数组的起始位置,destPos是目的数组起始位置
length是从src数组中复制的元素个数,注意越界问题
arraycopy可以复制基本类型数组和对象数组。但是如果复制对象数组,只是复制了对象的引用,而不是对象本身的拷贝,称为【浅复制】

int []arr1 = new int[6];
int []arr2 = new int[8];
Arrays.fill(arr1, 19);
Arrays.fill(arr2, 23);
System.arraycopy(arr1, 0, arr2, 0, arr1.length);
System.out.println(Arrays.toString(arr2));

数组的比较

1)Arrays类提供了重载后的equals()方法,用来比较整个数组;此方法针对所有基本类型与Object都做了重载
数组相等的条件是元素个数必须相等,且对应位置的元素也相等(对每个元素使用equals()判断)

int []arr1 = new int[8];
int []arr2 = new int[8];
Arrays.fill(arr1, 15);
Arrays.fill(arr2, 23);
System.out.println(Arrays.equals(arr1, arr2));

ps:多维数组的比较使用deepEquals()方法

String [][]st1 = {
		{"a","b","c"},
		{"d","e","f"}
};
String [][]st2 = {
		{"a","b","c"},
		{"d","e","f"}
};
System.out.println(Arrays.equals(st1,st2));//false
System.out.println(Arrays.deepEquals(st1, st2));//true

数组元素的比较

排序必须根据对象的实际类型执行比较操作,Java提供了两种方式来实现比较功能
1)实现java.lang.Comparable接口,Comparable接口只有compareTo()一个方法,
public int compareTo(Object o);
此方法接受另一个Object作为参数,若当前对象小于参数则返回负值,大于参数返回正值,相等则返回0;
实现了Comparable接口的类的对象可以用于sort()排序,如果未实现,调用sort()方法时会抛出ClassCastException异常

//如果未声明类型参数<T>,则compareTo()方法中默认的参数是Object
class People implements Comparable<People>{
	private int age;
	private String name;
	public People(int a,String n){
		this.age = a;
		this.name = n;
	}
	public int compareTo(People p1){
		if(this.age < p1.age)
			return (age - p1.age);
		else if(this.age > p1.age)
			return (age - p1.age);
		else{
			return this.name.compareTo(p1.name);
		}
	}
	/*@Override
	public int compareTo(Object o) {
		// TODO Auto-generated method stub
		return 0;
	}*/
}
People p1 = new People(16,"java1");
People p2 = new People(16,"jave6");
System.out.println(p1.compareTo(p2));
output:-4 (a的ASCII减去e的ASCII,结果为-4)

数组元素排序

即使用内置的排序方法Arrays.sort();可对任意的基本类型数组排序,也可以对任意对象数组排序(只需该类对象实现了Comparable接口或具有相关联的Comparator)
e.g:测试String类型,已实现了Comparable接口

String []arr = {"Java","C++","Beijing","NewYork","MySQL","jdbc","china"};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
Arrays.sort(arr,String.CASE_INSENSITIVE_ORDER);
//使用String.CASE_INSENSITIVE_ORDER忽略字母ASCII大小写的排序
System.out.println(Arrays.toString(arr));
output:
[Beijing, C++, Java, MySQL, NewYork, china, jdbc]
[Beijing, C++, china, Java, jdbc, MySQL, NewYork]

在已排序的数组中查找

如果数组已经排好序,那么可以使用Arrays.binarySearch()执行二分查找[Arrays.binarySearch(array[],type key);]
若找到了目标,binarySearch()返回元素的下标;否则它返回一个负值

String []arr = {"Java","C++","Beijing","NewYork","MySQL","jdbc ","china"};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
int pos = Arrays.binarySearch(arr, "MySQL");
System.out.println("Pos : " + pos);
output:[Beijing, C++, Java, MySQL, NewYork, china, jdbc]
Pos : 3

如果数组中包含重复的元素,则无法保证找到的就是这些副本中的哪一个,不过排序仍然可用

String []arr = {"Java","C++","Beijing","NewYork","MySQL",
				"jdbc","china","Java"
};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
int pos = Arrays.binarySearch(arr, "Java");
System.out.println("Pos : " + pos);
output:
[Beijing, C++, Java, Java, MySQL, NewYork, china, jdbc]
Pos : 3

猜你喜欢

转载自blog.csdn.net/qq_42413042/article/details/84661924