日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用append之后数组维度消失_JAVA魅力之神奇的数组带给你不一样的乐趣

發(fā)布時(shí)間:2024/10/8 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用append之后数组维度消失_JAVA魅力之神奇的数组带给你不一样的乐趣 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

咱也不知道咋想的,周末的的時(shí)候閑來沒事,因?yàn)榭吹揭坏罃?shù)組的面試題,我就跟數(shù)組杠上了,問題也不大,就是一個(gè)數(shù)組重寫的問題,我不知道大家有沒有遇到過類似的問題,在日常的開發(fā)環(huán)境中,反正我是沒遇到過,正常的開發(fā)就行,可能是因?yàn)槲夜緲I(yè)務(wù)的原因吧,哈哈哈哈

但是,我個(gè)人的愛好就是會(huì)看一些面試題,去考察自己的知識(shí)點(diǎn)掌握情況,以及和市場(chǎng)的動(dòng)態(tài),建議大家也可以這樣試一下,保持自己的競(jìng)爭(zhēng)力,所以,在看到這道面試題之后,我就想去試一下,然后就有了下面的代碼詳解

看正式代碼之前,關(guān)注我給我點(diǎn)動(dòng)力吧,讓我能更好的往下創(chuàng)作,嘿嘿嘿,好了,說正事

int類型數(shù)組

先來一個(gè)簡(jiǎn)單的內(nèi)容,這個(gè)是正常的,以為我在日常的開發(fā)中有的時(shí)候還是能遇見的,哈哈哈哈,正不正常就以我是不是用過作為標(biāo)準(zhǔn)

public class Main {

public static void main(String[] args) {

Array score=new Array(10);

for(int i=0;i<8;i++){

score.addLast(i);

}

score.add(1,100);

score.addLast(99);

System.out.println(score.toString());

System.out.println(score.find(1));

System.out.println(score.contains(1));

System.out.println(score.remove(1));

System.out.println(score.toString());

System.out.println(score.removeElement(2));

System.out.println(score.toString());

}

}

修改為泛型

public class Array {

private T[] data;

private int size;

public Array() {

this(10);

}

public Array(int capacity) {

//java本身不支持直接new 一個(gè)泛型數(shù)組,所以用以下方法實(shí)現(xiàn)

data = (T[])new Object[capacity];

size = 0;

}

public int getSize() {

return size;

}

public int getCapacity() {

return data.length;

}

public boolean isEmpty() {

return size == 0;

}

/**

* 向數(shù)組末尾添加元素

*

* @param e

*/

public void addLast(T e) {

add(size, e);

}

/**

* 向數(shù)組開頭添加元素

*

* @param e

*/

public void addFirst(T e) {

add(0, e);

}

/**

* 向任意合法位置添加元素

*

* @param index

* @param e

*/

public void add(int index, T e) {

if (size == data.length) {

throw new IllegalArgumentException("Add is fail.Array is full");

}

if (index < 0 || index > size) {

throw new IllegalArgumentException("Add is fail.Require index >= 0 and index < size");

}

for (int i = size; i > index; i--) {

data[i] = data[i - 1];

}

data[index] = e;

size++;

}

/**

* 獲取索引位置的元素

* 通過這種封裝,用戶無法查詢未使用的空間,保證了數(shù)據(jù)的安全性。

*

* @param index

* @return

*/

public T get(int index) {

if (index < 0 || index >= size) {

throw new IllegalArgumentException("Get is failed.Index is illegal");

}

return data[index];

}

/**

* 修改索引位置的元素

*

* @param index

* @param e

*/

public void set(int index, T e) {

if (index < 0 || index >= size) {

throw new IllegalArgumentException("Set is failed.Index is illegal");

}

data[index] = e;

}

/**

* 數(shù)組中是否包含某個(gè)元素

*

* @param e

* @return

*/

public boolean contains(T e) {

for (int i = 0; i < size; i++) {

//注意值的比較應(yīng)修改為equals方法

if (data[i].equals(e)) {

return true;

}

}

return false;

}

/**

* 查詢數(shù)組中某個(gè)元素的索引

*

* @param e

* @return 沒有該元素則返回-1

*/

public int find(T e) {

for (int i = 0; i < size; i++) {

if (data[i].equals(e)) {

return i;

}

}

return -1;

}

/**

* 刪除index位置的元素,并且返回該元素

* 不用擔(dān)心刪除后原來size位置的元素,因?yàn)橛脽o法訪問到它。

* 但是最好再寫一句data[size]=null 具體原因需要了解java的垃圾回收機(jī)制

*

* @param index

* @return

*/

public T remove(int index) {

if (index < 0 || index >= size) {

throw new IllegalArgumentException("Remove failed.Require index >=0 and index < size");

}

T ret = data[index];

for (int i = index; i < size - 1; i++) {

data[i] = data[i + 1];

}

//注意維護(hù)size

size--;

data[size]=null;

return ret;

}

/**

* 不用擔(dān)心數(shù)組為空的情況,因?yàn)閿?shù)組如果為空,remove方法就會(huì)拋出異常

* @return

*/

public T removeFirst(){

return remove(0);

}

public T removeLast(){

return remove(size-1);

}

/**

* 從數(shù)組中刪除元素e

* @param e

*/

public boolean removeElement(T e){

int index=find(e);

if(index!=-1){

remove(index);

return true;

}else{

return false;

}

}

/**

* 重寫toString()方法

*

* @return

*/

@Override

public String toString() {

StringBuilder res = new StringBuilder();

res.append(String.format("size= %d,capacity= %d", size, data.length));

res.append("[");

for (int i = 0; i < size; i++) {

res.append(data[i]);

if (i != size - 1) {

res.append(",");

}

}

res.append("]");

return res.toString();

}

}

那在添加之后,我們想的就是能不能動(dòng)態(tài)添加呢

增加數(shù)組大小

前面當(dāng)我們向數(shù)組中添加元素時(shí),如果index==size,表示數(shù)組已滿。

if (size == data.length) {

throw new IllegalArgumentException("Add is fail.Array is full");

}

現(xiàn)在可以考慮這樣做,依然判斷插入位置是否合法,但是當(dāng)size等于數(shù)組長度時(shí),自動(dòng)為數(shù)組擴(kuò)容——resize(2*data.length);

之所以是擴(kuò)為原來的2倍,是因?yàn)檫@樣擴(kuò)容量的大小和原來容量大小有關(guān),既不會(huì)過小也不會(huì)過大。

private void resize(int newCapacity){

T[] newData=(T[])new Object[newCapacity];

for(int i=0;i

newData[i]=data[i];

}

data=newData;

}

123456

減小數(shù)組大小

因?yàn)橛辛藃esize方法,實(shí)現(xiàn)起來就很簡(jiǎn)單了。在remove(int index)方法中,移除一個(gè)元素且維護(hù)size后,再加上對(duì)維護(hù)后的size的判斷,如下。如果size已經(jīng)變?yōu)閏apacity的一半,則將數(shù)組容量減半。

if(size==data.length/2){

resize(data.length/2);

}

注意

resize()方法設(shè)為私有,是為了用戶只需使用這個(gè)數(shù)組類,不必去顧慮數(shù)組的大小。

時(shí)間復(fù)雜度的分析

通過對(duì)addLast(T[] e)和removeLast(T[] e)時(shí)間復(fù)雜度的分析,我們發(fā)現(xiàn)都是O(n)級(jí)別的。但是,這樣一般性地考慮最壞的情況在這種情景下是沒有太大意義的。因?yàn)閍ddLast(T[] e)和removeLast(T[] e)操作并不會(huì)經(jīng)常觸發(fā)resize(int newCapcity)操作。所以用均攤復(fù)雜度分析的話,你會(huì)發(fā)現(xiàn)這兩個(gè)操作的均攤復(fù)雜度都是O(1)。因此resize(int newCapcity)這樣一個(gè)比較耗時(shí)的操作,如果保證不會(huì)每次都會(huì)觸發(fā),就可以將它的操作耗時(shí)分?jǐn)偟狡渌僮魃稀?/p>

現(xiàn)在再考慮另外一個(gè)場(chǎng)景,就是在addLast(T[] e)操作后,觸發(fā)了resize(int newCapcity),然后再removeLast(T[] e),又觸發(fā)了resize(int newCapcity);如此循環(huán)。像這樣addLast(T[] e)和removeLast(T[] e)的時(shí)間復(fù)雜度都是O(n)級(jí)別的,這就是所謂的復(fù)雜度的震蕩。以數(shù)組這個(gè)例子,之所以發(fā)生這種情況是因?yàn)槲覀冊(cè)趓emoveLast操作后,就接著進(jìn)行了resize操作這樣太著急了。那么該如何防止復(fù)雜度的震蕩呢?

可以這樣修改removeLast方法的代碼。

if(size==data.length/4 && data.length/4!=0){

resize(data.length/2);

}

加上data.length/4!=0的判斷是因?yàn)楫?dāng)data.length/4==0的時(shí)候,數(shù)組長度變?yōu)?,這是不合法的。

修改后的完整代碼

public class Array {

private T[] data;

private int size;

public Array() {

this(10);

}

public Array(int capacity) {

//java本身不支持直接new 一個(gè)泛型數(shù)組,所以用以下方法實(shí)現(xiàn)

data = (T[])new Object[capacity];

size = 0;

}

public int getSize() {

return size;

}

public int getCapacity() {

return data.length;

}

public boolean isEmpty() {

return size == 0;

}

/**

* 向數(shù)組末尾添加元素

*

* @param e

*/

public void addLast(T e) {

add(size, e);

}

/**

* 向數(shù)組開頭添加元素

*

* @param e

*/

public void addFirst(T e) {

add(0, e);

}

/**

* 向任意合法位置添加元素

*

* @param index

* @param e

*/

public void add(int index, T e) {

/*if (size == data.length) {

throw new IllegalArgumentException("Add is fail.Array is full");

}*/

if (index < 0 || index > size) {

throw new IllegalArgumentException("Add is fail.Require index >= 0 and index < size");

}

if(size == data.length){

resize(2*data.length);

}

for (int i = size; i > index; i--) {

data[i] = data[i - 1];

}

data[index] = e;

size++;

}

/**

* 獲取索引位置的元素

* 通過這種封裝,用戶無法查詢未使用的空間,保證了數(shù)據(jù)的安全性。

*

* @param index

* @return

*/

public T get(int index) {

if (index < 0 || index >= size) {

throw new IllegalArgumentException("Get is failed.Index is illegal");

}

return data[index];

}

/**

* 修改索引位置的元素

*

* @param index

* @param e

*/

public void set(int index, T e) {

if (index < 0 || index >= size) {

throw new IllegalArgumentException("Set is failed.Index is illegal");

}

data[index] = e;

}

/**

* 數(shù)組中是否包含某個(gè)元素

*

* @param e

* @return

*/

public boolean contains(T e) {

for (int i = 0; i < size; i++) {

//注意值的比較應(yīng)修改為equals方法

if (data[i].equals(e)) {

return true;

}

}

return false;

}

/**

* 查詢數(shù)組中某個(gè)元素的索引

*

* @param e

* @return 沒有該元素則返回-1

*/

public int find(T e) {

for (int i = 0; i < size; i++) {

if (data[i].equals(e)) {

return i;

}

}

return -1;

}

/**

* 刪除index位置的元素,并且返回該元素

* 不用擔(dān)心刪除后原來size位置的元素,因?yàn)橛脽o法訪問到它。

* 但是最好再寫一句data[size]=null 具體原因需要了解java的垃圾回收機(jī)制

*

* @param index

* @return

*/

public T remove(int index) {

if (index < 0 || index >= size) {

throw new IllegalArgumentException("Remove failed.Require index >=0 and index < size");

}

T ret = data[index];

for (int i = index; i < size - 1; i++) {

data[i] = data[i + 1];

}

//注意維護(hù)size

size--;

data[size]=null;

if(size==data.length/4 && data.length/4!=0){

resize(data.length/2);

}

return ret;

}

/**

* 不用擔(dān)心數(shù)組為空的情況,因?yàn)閿?shù)組如果為空,remove方法就會(huì)拋出異常

* @return

*/

public T removeFirst(){

return remove(0);

}

public T removeLast(){

return remove(size-1);

}

/**

* 從數(shù)組中刪除元素e

* @param e

*/

public boolean removeElement(T e){

int index=find(e);

if(index!=-1){

remove(index);

return true;

}else{

return false;

}

}

/**

* 重寫toString()方法

*

* @return

*/

@Override

public String toString() {

StringBuilder res = new StringBuilder();

res.append(String.format("size= %d,capacity= %d", size, data.length));

res.append("[");

for (int i = 0; i < size; i++) {

res.append(data[i]);

if (i != size - 1) {

res.append(",");

}

}

res.append("]");

return res.toString();

}

private void resize(int newCapacity){

T[] newData=(T[])new Object[newCapacity];

for(int i=0;i

newData[i]=data[i];

}

data=newData;

}

}

推薦

最后忍不住展示一下markdown寫作軟件的截圖,因?yàn)樗鼘?shí)在是太美了。

  • 好了,基本就整理了這一些,我不會(huì)說我就想到了這一些的,畢竟一個(gè)人的想法還是有限的,希望大家能夠在下面的評(píng)論區(qū)和我討論,大家一起學(xué)習(xí)成長,關(guān)注我,一個(gè)腦回路清奇的程序員

總結(jié)

以上是生活随笔為你收集整理的使用append之后数组维度消失_JAVA魅力之神奇的数组带给你不一样的乐趣的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。