欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java的增強(qiáng)for循環(huán)修改數(shù)組元素的問題小結(jié)

 更新時(shí)間:2024年02月07日 10:33:28   作者:Violet_Stray  
增強(qiáng)for循環(huán)的元素變量x,就是一個(gè)局部變量,它是引用數(shù)組當(dāng)前元素引用的副本(就相當(dāng)于上文所說的你復(fù)刻朋友的鑰匙),或者是基本數(shù)據(jù)類型的值的副本,這篇文章主要介紹了Java的增強(qiáng)for循環(huán)修改數(shù)組元素的問題小結(jié),需要的朋友可以參考下

曾經(jīng)沒怎么多想過for each有什么特殊的地方,以為就是for循環(huán)的簡便寫法,直到今天寫力扣發(fā)現(xiàn)了不對勁,使用for each就是過不了,而用正規(guī)for循環(huán)就過了,決定來好好了解一下for each。
而有時(shí)候?qū)懺鰪?qiáng)for循環(huán)又可以修改屬性
最后發(fā)現(xiàn),是否能理解for each的修改與是否理解Java是值傳遞有很大的關(guān)系。

(完整代碼放在最后)

決定從基本數(shù)據(jù)類型和引用數(shù)據(jù)類型兩種類型來看。

首先簡單看一下for each的遍歷:
自定義了一個(gè)Person類,有name(String)和age(int)兩個(gè)屬性。
用int數(shù)組代表基本數(shù)據(jù)類型的數(shù)組,用String類和Person類代表引用數(shù)據(jù)類型的數(shù)組
輸出結(jié)果都放在了注釋里面:

public class Main {
	public static void main(String[] args) {
		// 1.能成功遍歷基本數(shù)據(jù)類型的數(shù)組元素
		int[] nums = { 1, 2, 3, 4, 5 };
		for (int i : nums) {
			System.out.print(i + "\t");
		}
		// 輸出:1 2 3 4 5
		System.out.println();
		// 2.能成功遍歷引用數(shù)據(jù)類型的數(shù)組元素
		String[] strs = { "acd", "qwe", "oiu" };
		for (String string : strs) {
			System.out.print(string + "\t");
		}
		// 輸出:acd qwe oiu
		System.out.println();
		Person[] persons = { new Person("張三", 12), new Person("李四", 33), new Person("王五", 90) };
		for (Person person : persons) {
			System.out.print(person + "\t");
		}
		// 輸出:Person [name=張三, age=12] Person [name=李四, age=33] Person [name=王五, age=90]
		System.out.println("-----------------------------------------------------------");
}
class Person {
	String name;
	int age;
	public Person() {
		super();
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
}

再來看看使用for each來修改數(shù)據(jù):(和上面代碼重復(fù)的內(nèi)容不再寫)

public class Main {
	public static void main(String[] args) {
		//這些數(shù)據(jù)沒有變
		int[] nums = { 1, 2, 3, 4, 5 };
		String[] strs = { "acd", "qwe", "oiu" };
		Person[] persons = { new Person("張三", 12), new Person("李四", 33), new Person("王五", 90) };
		// 3.修改基本數(shù)據(jù)類型的數(shù)組元素的值
		for (int i : nums) {
			if (i == 4) {
				i = 233;
				System.out.println("已修改");
			}
		}
		for (int i : nums) {
			System.out.print(i + "\t");
		}
		// 輸出:1 2 3 4 5
		// 說明nums數(shù)組并未修改
		System.out.println();
		// 4.修改引用數(shù)據(jù)類型的數(shù)組元素的值
		for (String string : strs) {
			if (string.equals("acd")) {
				string = "hello world";
				System.out.println("已修改");
			}
		}
		for (String string : strs) {
			System.out.print(string + "\t");
		}
		// 輸出:acd qwe oiu
		// 說明str數(shù)組并未修改
		System.out.println();
		for (Person person : persons) {
			if (person.name.equals("張三")) {
				person.age = 100;
				System.out.println("已修改");
			}
		}
		for (Person person : persons) {
			System.out.print(person + "\t");
		}
		// 輸出:Person [name=張三,age=100] Person [name=李四,age=33] Person [name=王五,age=90]
		// 說明persons數(shù)組有修改
		System.out.println();
	}
}

結(jié)果:int數(shù)組和String數(shù)組多沒能成功修改,而只有Person數(shù)組成功修改了

為什么Person數(shù)組能修改成功呢?因?yàn)镴ava是值傳遞。能理解這個(gè)非常重要!

(理解的朋友可以跳過下面這一段)

理解Java是值傳遞:

首先什么是值傳遞,什么是引用傳遞呢?

  • 值傳遞是指在調(diào)用函數(shù)時(shí)將實(shí)際參數(shù)復(fù)制一份傳遞到函數(shù)中,這樣在函數(shù)中如果對參數(shù)進(jìn)行修改,將不會影響到實(shí)際參數(shù)。
  • 引用傳遞是指在調(diào)用函數(shù)時(shí)將實(shí)際參數(shù)的地址直接傳遞到函數(shù)中,那么在函數(shù)中對參數(shù)所進(jìn)行的修改,將影響到實(shí)際參數(shù)

主要區(qū)別就在于是否將實(shí)際參數(shù)復(fù)制

那為什么說Java是值傳遞呢?按照這么說,Java其實(shí)是將實(shí)際參數(shù)復(fù)制過傳遞到函數(shù)中的呀!
有人舉例說把int等基本數(shù)據(jù)類型作為參數(shù),并不能修改實(shí)參的值,能說明Java是值傳遞,而傳遞Person這種自定義的類,在函數(shù)中修改屬性之后,在主函數(shù)中調(diào)用卻能成功修改,這并不能說明Java是值傳遞,反而像引用傳遞呀?

曾經(jīng)看到一個(gè)例子:

  • 你的朋友借給你一把鑰匙,你朋友就相當(dāng)于主函數(shù),你相當(dāng)于主函數(shù)中調(diào)用的另一個(gè)函數(shù),鑰匙就是實(shí)參,你這個(gè)函數(shù)就相當(dāng)于進(jìn)入朋友家中,干一些事情之后離開。你拿著這把鑰匙,能打開他們家的大門,于是你進(jìn)了他們家,砸壞了他們家的電視機(jī)(相當(dāng)于修改Person類的屬性)。當(dāng)這個(gè)函數(shù)結(jié)束的時(shí)候,就相當(dāng)于你已經(jīng)離開了你朋友的家中。你朋友拿著鑰匙打開了自家的門,發(fā)現(xiàn)電視機(jī)被砸壞了(相當(dāng)于你在輸出端看到在主屬性Print的Person的屬性值被修改了),于是朋友把你揍了一頓。

所以說在子函數(shù)中修改屬性,這個(gè)屬性并非是傳遞進(jìn)來的參數(shù)。傳遞進(jìn)來的參數(shù)是鑰匙!而不是會被砸的電視機(jī)!
Java是值傳遞可以理解為,你拿著你朋友家的鑰匙又復(fù)刻了一把,所以現(xiàn)在有兩把鑰匙。你和你朋友都能用兩把鑰匙打開朋友家的門!
意思就是有兩個(gè)引用同時(shí)指向了同一個(gè)地址,第二個(gè)復(fù)制的引用正是子函數(shù)中的局部變量。無論是用哪一個(gè)引用對屬性修改,都能直接在內(nèi)存中修改,于是會出現(xiàn)傳遞Person類修改屬性會看到成功修改的結(jié)果。

如何體現(xiàn)值傳遞的特征呢——修改傳遞過來的值,并不會影響原來的對象:
就好比,你在復(fù)刻的鑰匙上寫下自己的名字,你朋友的鑰匙上并不會出現(xiàn)你的名字。
就意味著你用子函數(shù)中的引用去指向一個(gè)新對象,而主函數(shù)中的引用并不會去指向那個(gè)新對象一樣,還是指向原來的對象。

所以說Java是值傳遞,而并發(fā)引用傳遞!

回到增強(qiáng)for循環(huán):

for(元素類型t 元素變量x : 遍歷對象obj){ 
     引用了x的java語句; 
} 

增強(qiáng)for循環(huán)的元素變量x,就是一個(gè)局部變量,它是引用數(shù)組當(dāng)前元素引用的副本(就相當(dāng)于上文所說的你復(fù)刻朋友的鑰匙),或者是基本數(shù)據(jù)類型的值的副本。

可以這么理解:

int[] nums = { 1, 2, 3, 4, 5 };
for (int i : nums) {
	if (i == 4) {
		i = 233;		
	}
}
//相當(dāng)于:
for(int j=0;j<nums.length;j++){
	int i=nums[j];
	if(i==4){
		i=233;
	}
	//所以說修改對于原數(shù)組根本沒有任何影響
}

對于String數(shù)組相當(dāng)于:

for (int j = 0; j < strs.length; j++) {
			String i = strs[j];
			if (i.equals("acd")) {
				i = "hello world";
			}
		}
		//String類是不可變對象,所以這里也沒有任何影響
		//輸出:acd	qwe	oiu

對于Person類相當(dāng)于:

for(int j=0;j<persons.length;j++) {
			Person i=persons[j];
			if (i.name.equals("張三")) { 
				i.age = 100; //這里改變的是persons[j].age,而不是persons[j]本身,所以能成功改變
			}
		}

如果是這樣:

for (int j = 0; j < persons.length; j++) {
			Person i = persons[j];
			if (i.name.equals("李四")) {
				i = new Person("A", 80); //i指向一個(gè)新對象,輸出結(jié)果也毫無變化,不會輸出(A,80)
			}
		}

總而言之:如果想要修改元素就用正規(guī)for循環(huán),不要使用增強(qiáng)for循環(huán)。

所有的代碼:

public class Main {
	public static void main(String[] args) {
		// 1.能成功遍歷基本數(shù)據(jù)類型的數(shù)組元素
		int[] nums = { 1, 2, 3, 4, 5 };
		for (int i : nums) {
			System.out.print(i + "\t");
		}
		// 輸出:1 2 3 4 5
		System.out.println();
		// 2.能成功遍歷引用數(shù)據(jù)類型的數(shù)組元素
		String[] strs = { "acd", "qwe", "oiu" };
		for (String string : strs) {
			System.out.print(string + "\t");
		}
		// 輸出:acd qwe oiu
		System.out.println();
		Person[] persons = { new Person("張三", 12), new Person("李四", 33), new Person("王五", 90) };
		for (Person person : persons) {
			System.out.print(person + "\t");
		}
		// 輸出:Person [name=張三, age=12] Person [name=李四, age=33] Person [name=王五, age=90]
		System.out.println();
		System.out.println("-----------------------------------------------------------");
		// 3.修改基本數(shù)據(jù)類型的數(shù)組元素的值
		for (int i : nums) {
			if (i == 4) {
				i = 233;
				System.out.println("已修改");
			}
		}
		for (int i : nums) {
			System.out.print(i + "\t");
		}
		// 輸出:1 2 3 4 5
		// 說明nums數(shù)組并未修改
		System.out.println();
		// 4.修改引用數(shù)據(jù)類型的數(shù)組元素的值
		for (String string : strs) {
			if (string.equals("acd")) {
				string = "hello world";
				System.out.println("已修改");
			}
		}
		for (String string : strs) {
			System.out.print(string + "\t");
		}
		// 輸出:acd qwe oiu
		// 說明str數(shù)組并未修改
		System.out.println();
		for (Person person : persons) {
			if (person.name.equals("張三")) {
				person.age = 100;
				System.out.println("已修改");
			}
		}
		for (Person person : persons) {
			System.out.print(person + "\t");
		}
		// 輸出:Person [name=張三,age=100] Person [name=李四,age=33] Person [name=王五,age=90]
		// 說明persons數(shù)組有修改
		System.out.println();
		System.out.println("-----------------------------------------------------------");
		// int數(shù)組相當(dāng)于:
		for (int j = 0; j < nums.length; j++) {
			int i = nums[j];
			if (i == 4) {
				i = 233;
			}
			// 所以說修改對于原數(shù)組根本沒有任何影響
		}
		for (int i : nums) {
			System.out.print(i + "\t");
		}
		System.out.println();
		// String類相當(dāng)于
		for (int j = 0; j < strs.length; j++) {
			String i = strs[j];
			if (i.equals("acd")) {
				i = "hello world";
			}
		}
		for (String string : strs) {
			System.out.print(string + "\t");
		}
		System.out.println();
		// Person類相當(dāng)于:
		persons = { new Person("張三", 12), new Person("李四", 33), new Person("王五", 90) };
		for (int j = 0; j < persons.length; j++) {
			Person i = persons[j];
			if (i.name.equals("張三")) {
				i.age = 100; // 這里改變的是persons[j].age,而不是persons[j]本身,所以能成功改變
			}
			if (i.name.equals("李四")) {
				i = new Person("A", 80); // i指向一個(gè)新對象,輸出結(jié)果也毫無變化,不會輸出(A,80)
			}
		}
		for (Person person : persons) {
			System.out.print(person + "\t");
		}
	}
}
class Person {
	String name;
	int age;
	public Person() {
		super();
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
}

到此這篇關(guān)于關(guān)于Java的增強(qiáng)for循環(huán)修改數(shù)組元素的問題的文章就介紹到這了,更多相關(guān)Java增強(qiáng)for循環(huán)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Mac Book中Java環(huán)境變量設(shè)置的方法

    Mac Book中Java環(huán)境變量設(shè)置的方法

    本文給大家介紹mac book 中設(shè)置java環(huán)境變量的方法,非常不錯,具有參考借鑒價(jià)值,需要的朋友參考下
    2017-04-04
  • java判斷今天,昨天,前天,不能用秒間隔的簡單實(shí)例

    java判斷今天,昨天,前天,不能用秒間隔的簡單實(shí)例

    下面小編就為大家?guī)硪黄猨ava判斷今天,昨天,前天,不能用秒間隔的簡單實(shí)例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-03-03
  • 淺談Java父子類加載順序

    淺談Java父子類加載順序

    本文主要介紹了Java父子類加載順序,那么這么長怎么記呀?本文就幫大家總結(jié)一下,更有利于記憶,感興趣的可以了解一下
    2021-08-08
  • 詳解Java多線程編程中的線程同步方法

    詳解Java多線程編程中的線程同步方法

    這篇文章主要介紹了Java多線程編程中的線程同步方法,使用synchronized關(guān)鍵字創(chuàng)建線程同步方法是實(shí)現(xiàn)線程同步的關(guān)鍵,需要的朋友可以參考下
    2016-05-05
  • Java中的IP地址和InetAddress類使用詳解

    Java中的IP地址和InetAddress類使用詳解

    這篇文章主要介紹了Java中的IP地址和InetAddress類使用詳解,是Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-10-10
  • Java 利用DeferredResult實(shí)現(xiàn)http輪詢實(shí)時(shí)返回?cái)?shù)據(jù)接口

    Java 利用DeferredResult實(shí)現(xiàn)http輪詢實(shí)時(shí)返回?cái)?shù)據(jù)接口

    這篇文章主要介紹了Java 利用 DeferredResult 實(shí)現(xiàn) http 輪詢實(shí)時(shí)返回?cái)?shù)據(jù)接口,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下
    2021-03-03
  • JDBC連接Mysql的5種方式實(shí)例總結(jié)

    JDBC連接Mysql的5種方式實(shí)例總結(jié)

    JDBC是Java DataBase Connectivity技術(shù)的簡稱,是一種可用于執(zhí)行 SQL語句的Java API,下面這篇文章主要給大家介紹了關(guān)于JDBC連接Mysql的5種方式,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-04-04
  • JDK14新特性之switch表達(dá)式的實(shí)現(xiàn)

    JDK14新特性之switch表達(dá)式的實(shí)現(xiàn)

    這篇文章主要介紹了JDK14新特性之switch表達(dá)式的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • java 語句塊的使用詳解及實(shí)例

    java 語句塊的使用詳解及實(shí)例

    這篇文章主要介紹了java 用語句塊的正確方法實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • Java實(shí)現(xiàn)基于token認(rèn)證的方法示例

    Java實(shí)現(xiàn)基于token認(rèn)證的方法示例

    這篇文章主要介紹了Java實(shí)現(xiàn)基于token認(rèn)證的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08

最新評論