您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“Java中復(fù)合數(shù)據(jù)類型怎么用”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“Java中復(fù)合數(shù)據(jù)類型怎么用”這篇文章吧。
在 Java 中字符串被作為 String 類型的對(duì)象處理。 String 類位于 java.lang 包中,默認(rèn)情況下該包自動(dòng)導(dǎo)入。
String對(duì)象創(chuàng)建后不會(huì)被修改,當(dāng)我們修改某個(gè)字符串對(duì)象實(shí)際上是將原引用指向了新創(chuàng)建的內(nèi)存空間。并且相同的字符串常量Java不會(huì)分配兩個(gè)內(nèi)存空間,而是將兩個(gè)引用指向相同的空間。
public class MyString { public static void main(String[] args) { String s1="字符串"; String s2="字符串"; String s3=s1; System.out.println(s1==s2); // s1、s2字符串內(nèi)容相同,指向相同的內(nèi)存空間,輸出:true System.out.println(s1==s3); // 修改之前s1與s3相同,輸出:true s1="修改字符串"; System.out.println(s1==s3); // 修改之后s1指向新的內(nèi)存空間,與s3不同,輸出:false } }
String中常用的方法:
str.length() //返回當(dāng)前字符串的長(zhǎng)度 str.indexOf(int ch) //查找ch字符在該字符串中第一次出現(xiàn)的位置,若無(wú)返回-1 str.indexOf(subStr) //查找str子字符串在該字符串中第一次出現(xiàn)的位罝 str.lastIndexOf(ch) //查找ch字符在該字符串中最后一次出現(xiàn)的位置 str.lastlndexOf(subStr)查找St子字符串在該字符串中最后一次出現(xiàn)的位置 str.substring(beginlndex) //獲取從beginlndex位置幵始到結(jié)朿的子字符串 str.substring(beginlndex, endlndex) //獲取從beginlndex位置幵始到endlndex位M的子字符串 str.trim() //返回去除了前后空格的字符串 str.equals(obj) //將該字符串與指定對(duì)象比較,返回true或false str.toLowerCase() //將字符串轉(zhuǎn)換為小寫 str.toUpperCase() //將字符串轉(zhuǎn)換為大寫 str.charAt(int index) //獲取字符串中指定位置的字符 str.setCharAt(i,c) //設(shè)置某個(gè)位置的字符串 str.split(String regex, int limit) //將字符串分割為子字符串,返回字符串?dāng)?shù)組 str.concat(str2) //將str2拼接到末尾 str.getBytes() /將該字符串轉(zhuǎn)換為byte數(shù)組 str.toCharArray() //轉(zhuǎn)化為字符數(shù)組
如果需要使用經(jīng)常修改的字符串,可以用StringBuilder類來(lái)保存,可以通過(guò)append、replace等方法對(duì)字符串進(jìn)行修改,修改之后仍然指向同一塊內(nèi)存地址
public class MyString { public static void main(String[] args) { StringBuilder s4=new StringBuilder("初始字符串"); StringBuilder s5=s4; s4.replace(0,10,"修改后的字符串"); System.out.println(s4); System.out.println(s4==s5); // 修改后仍然指向同一塊內(nèi)存,因此輸出:true } }
通過(guò)String.valueOf()可以將其他類型數(shù)據(jù)轉(zhuǎn)化為字符串。
char[] arr={'a', 'd', 'e'}; String s=String.valueOf(arr);
Java中的基本數(shù)據(jù)類型如int、double等都不具有對(duì)象的特性,為了像其他對(duì)象一樣擁有自己的方法,Java為每個(gè)基本數(shù)據(jù)類型提供了包裝類,像對(duì)象那樣來(lái)操作基本數(shù)據(jù)類型。包裝類的基本方法用于實(shí)現(xiàn)類型之間的相互轉(zhuǎn)換。
Java包裝類可以自動(dòng)裝箱/拆箱,即通過(guò)=運(yùn)算符自動(dòng)完成基本類型和包裝類之間的類型轉(zhuǎn)換。
// 定義int類型變量,值為86 int score1 = 86; // 使用int創(chuàng)建Integer包裝類對(duì)象,手動(dòng)裝箱 Integer score2=new Integer(score1); Integer score2=score1; //自動(dòng)裝箱 // 將Integer包裝類轉(zhuǎn)換為double類型 double score3=score2.doubleValue(); // 將Integer包裝類轉(zhuǎn)換為float類型 float score4=score2.floatValue(); // 將Integer包裝類轉(zhuǎn)換為int類型,手動(dòng)拆箱 int score5 =score2.intValue(); int score5 = score2 // 自動(dòng)拆箱 // 將字符串轉(zhuǎn)為int int score6 = Integer.parseInt("666");
基本類型與字符串之間的互相轉(zhuǎn)換:
通過(guò)Integer.MAX_VALUE可以獲得最大整數(shù)值
使用 java.util 包中的 Date 類可以創(chuàng)建時(shí)間對(duì)象,使用java.text 包中的 SimpleDateFormat 類可以將時(shí)間轉(zhuǎn)化為所需格式的字符串,其中 “yyyy-MM-dd HH:mm:ss” 為預(yù)定義字符串, yyyy 表示四位年, MM 表示兩位月份, dd 表示兩位日期, HH 表示小時(shí)(使用24小時(shí)制), mm 表示分鐘, ss 表示秒,這樣就指定了轉(zhuǎn)換的目標(biāo)格式,最后調(diào)用 format() 方法將時(shí)間對(duì)象Date轉(zhuǎn)換為指定的格式的字符串,反之parse()方法可以將普通字符串轉(zhuǎn)化為Date對(duì)象。
java.util.Calendar 類可以更加方便地進(jìn)行時(shí)間的處理,通過(guò)調(diào)用 getInstance() 靜態(tài)方法獲取一個(gè) Calendar 對(duì)象,默認(rèn)代表當(dāng)前時(shí)間,可以通過(guò)c.getTime()將其轉(zhuǎn)化為Date對(duì)象。Calendar對(duì)象的更多方法如下
Math 類位于 java.lang 包中,包含用于執(zhí)行基本數(shù)學(xué)運(yùn)算的方法, Math 類的所有方法都是靜態(tài)方法,所以使用該類中的方法時(shí),可以直接使用類名.方法名,如: Math.round();
int minNum=Math.min(2, 3); //獲取最小值 int maxNum=Math.max(2, 3); //獲取最大值 long round=Math.round(3.1415); //四舍五入 double floor=Math.floor(3.1415); //向下取整 double ceil=Math.ceil(3.1415); //向上取整 double random=Math.random(); //取[0,1)之間的隨機(jī)數(shù)
在各種基本數(shù)據(jù)類型的基礎(chǔ)上,Java使用集合類當(dāng)作容器來(lái)儲(chǔ)存具有相同屬性的對(duì)象。通過(guò)集合類組織數(shù)據(jù)可以實(shí)現(xiàn)對(duì)特定數(shù)據(jù)的快速插入、刪除與查詢操作。而且與數(shù)組相比,集合的長(zhǎng)度靈活可變,而且查找方式也不只有下標(biāo)一種。Java中常見的集合類分為兩個(gè)接口Collection和Map,其中Collection有三個(gè)子接口鏈表List、隊(duì)列Queue、集Set,List常見的實(shí)現(xiàn)類為數(shù)組序列ArrayList,Queue實(shí)現(xiàn)類為L(zhǎng)inkedList稱為鏈表,Set實(shí)現(xiàn)類為哈希集。Collection中按照一個(gè)一個(gè)對(duì)象來(lái)存儲(chǔ)數(shù)據(jù),Map中按照鍵值對(duì)<key,value>來(lái)存儲(chǔ)數(shù)據(jù)。
Collection接口規(guī)定了ArrayList、Set等具體實(shí)現(xiàn)類的接口方法,例如它們都使用add()方法來(lái)添加元素,因此一些方法名在各個(gè)類實(shí)現(xiàn)中是通用的。
ArrayList是類似于數(shù)組的容器,將對(duì)象儲(chǔ)存進(jìn)ArrayList之中便于組織和管理。通過(guò)add()方法可以將單個(gè)對(duì)象插入列表,addAll()可以將多個(gè)對(duì)象組成的子列表插入父列表中,插入時(shí)可以指定插入的位置,可以通過(guò)Arrays.asList()將數(shù)組轉(zhuǎn)化為列表,通過(guò)toArray()方法可以將列表轉(zhuǎn)為Object[]數(shù)組,可以向其中傳入泛型參數(shù)從而返回特定類型的數(shù)組。
需要注意的是通過(guò)Arrays.asList()轉(zhuǎn)化成的List長(zhǎng)度是固定的,不能進(jìn)行add()操作,會(huì)報(bào)錯(cuò);我們可以將其作為子列表添加到一個(gè)新的List列表,然后再進(jìn)行插入操作。
例如向列表courseList中插入Course對(duì)象:
public void addCourse(){ Course c1=new Course(1,"數(shù)據(jù)結(jié)構(gòu)"); Course c2=new Course(2,"操作系統(tǒng)"); Course[] cArr={new Course(3,"組成原理"),new Course(4,"計(jì)算機(jī)網(wǎng)絡(luò)")}; courseList.add(c1); // 向數(shù)組列表中添加對(duì)象 courseList.add(0,c2); // 向指定位置添加對(duì)象 courseList.addAll(Arrays.asList(cArr)); // 向列表中添加子列表,前加數(shù)字表示插入位置 Course tmp=(Course)courseList.get(0); // 從列表中取出對(duì)象 Course[] courseArr=courseList.toArray(new Course[courseList.size()]); // 轉(zhuǎn)換為特定類型的數(shù)組 }
特別地,int[]與List<Integer>之間無(wú)法直接使用asList()/toArray()方法進(jìn)行互相轉(zhuǎn)換,可以經(jīng)過(guò)如下流操作,或者遍歷int[]逐個(gè)添加到List
int[] nums=new int[]{3,1,5,8}; //arr轉(zhuǎn)list List<Integer> numList = Arrays.stream(nums).boxed().collect(Collectors.toList()); //list轉(zhuǎn)arr int[] arr = numList.stream().mapToInt(Integer::valueOf).toArray();
通過(guò)size()方法可以獲取列表長(zhǎng)度,通過(guò)get()方法可以獲取指定位置的對(duì)象,進(jìn)而通過(guò)for循環(huán)遍歷每個(gè)對(duì)象,也可以使用for each的方式遍歷每個(gè)元素。還可以通過(guò)迭代器實(shí)現(xiàn)對(duì)每個(gè)對(duì)象的訪問(wèn)。值得注意的是,每個(gè)對(duì)象在列表中都是以O(shè)bject對(duì)象的方式儲(chǔ)存的,因此在取出之后需要通過(guò)強(qiáng)制類型轉(zhuǎn)換為原來(lái)的對(duì)象類型,例如(Course)轉(zhuǎn)為Course類的對(duì)象
public void showCourse(){ int listLength=courseList.size(); // 獲取列表長(zhǎng)度 for (int i=0;i<listLength;i++) { Course c=(Course)courseList.get(i); // 獲取列表第i個(gè)元素 System.out.println(c.name); } } public void iteratorCourse(){ Iterator it=courseList.iterator(); // 獲取迭代器 while (it.hasNext()){ // 如果仍有下一個(gè)元素 Course c=(Course)it.next(); // 取出下一個(gè)元素 System.out.println(c.name); } }
通過(guò)set()方法對(duì)列表指定位置的元素進(jìn)行修改。通過(guò)remove()方法移除指定位置或者指定對(duì)象。通過(guò)removeAll()刪除父列表中包含的所有子列表中的元素,通過(guò)clear()可以清空列表。
public void modifyCourse(){ courseList.set(2,new Course(5,"離散數(shù)學(xué)")); // 修改2位置上的對(duì)象 } public void removeCourse(){ courseList.remove(3); // 刪除3位置上的對(duì)象 Course c1= (Course) courseList.get(1); Course c2=(Course) courseList.get(2); courseList.remove(c1); // 刪除指定對(duì)象 Course[] cArr={c1,c2}; courseList.removeAll(Arrays.asList(cArr)); // 刪除courseList中所包含的cArr的元素 }
通過(guò)contains()、containsAll()方法判斷List是否包含某個(gè)或者某幾個(gè)對(duì)象,其實(shí)現(xiàn)原理是遍歷List中的每個(gè)對(duì)象調(diào)用其equals()方法和目標(biāo)對(duì)象進(jìn)行比較,如果存在返回true,否則返回false。因此我們可以重寫Course類的equals()方法,進(jìn)而調(diào)用contains()方法判斷List中是否包含指定Course對(duì)象。類似地indexOf()方法可以通過(guò)調(diào)用equals()找到元素在List中第一次出現(xiàn)的位置。
// 重寫Course類的equals()方法 public boolean equals(Object o) { if (this == o) return true; // 如果兩個(gè)對(duì)象的地址相同,肯定相同 if (!(o instanceof Course)) return false; Course course = (Course) o; return id == course.id && // 判斷兩個(gè)Course對(duì)象的id和name相同 name.equals(course.name); } // 在CourseList中調(diào)用contains()判讀是否包含某個(gè)對(duì)象 public void containCourse(){ Course nc=new Course(5,"數(shù)據(jù)結(jié)構(gòu)"); if(courseList.contains(nc)) { // 判斷List中是否包含Course對(duì)象nc int index = courseList.indexOf(nc); // 獲取元素在List中的位置 System.out.println("列表中包含該課程,位置:" + index); } }
之前提到集合中存放的都是對(duì)象的引用(Object),每次存入時(shí)集合會(huì)忽略對(duì)象的具體類型,有時(shí)存入其他類型對(duì)象則會(huì)在運(yùn)行時(shí)出錯(cuò),而且每次取出時(shí)則需要進(jìn)行類型的強(qiáng)制轉(zhuǎn)換還原回來(lái)。可以使用泛型規(guī)定某個(gè)集合只能存放特定類型或者其子類型的對(duì)象,這樣就會(huì)在編譯期間進(jìn)行類型檢查,而且在取出時(shí)可以直接返回特定類型的對(duì)象。注意泛型不能用于基本數(shù)據(jù)類型,例如List <int>會(huì)報(bào)錯(cuò),而應(yīng)該使用其包裝類List <Integer>。
// 創(chuàng)建元素類型為Course的列表 public List<Course> courseList=new ArrayList<Course>(); public void addCourse(){ Course c=new Course(6,"數(shù)據(jù)結(jié)構(gòu)"); courseList.add(c); // courseList.add("字符串"); // 嘗試向列表中添加非Course類型的對(duì)象,報(bào)錯(cuò) Course c2=courseList.get(0); // 可以直接取出為Course類型對(duì)象 System.out.println(c2.name); }
通過(guò)集合的工具類Collections.sort()方法可以實(shí)現(xiàn)對(duì)List對(duì)象的排序,其實(shí)現(xiàn)的原理是調(diào)用每個(gè)元素的compareTo()方法實(shí)現(xiàn)對(duì)象之間的比較進(jìn)而排序。因此每個(gè)對(duì)象必須是可比較的類型,即必須實(shí)現(xiàn)了Comparable 接口的對(duì)象,如下所示首先定義可比較類Student,再定義學(xué)生列表studentLis添加學(xué)生對(duì)象后,調(diào)用Collections.sort()方法對(duì)列表進(jìn)行排序,或者直接使用studentList.sort()。
public class Student implements Comparable<Student> { // 定義Student類實(shí)現(xiàn)Comparable接口 public String name; public int id; public Student(int id, String name) { this.name = name; this.id = id; } @Override public int compareTo(Student o) { // 實(shí)現(xiàn)接口的方法,根據(jù)id大小對(duì)學(xué)生進(jìn)行比較 if (this.id>o.id){ // 如果大于o返回1 return 1; }else if (this.id<o.id){ // 小于返回-1 return -1; }else { // 等于返回0 return 0; } } } public class ListSort { public List<Student> studentList=new ArrayList<Student>(); // 學(xué)生列表 public void sortStudent(){ Student s1=new Student(1011,"小明"); Student s2=new Student(1005,"小趙"); Student s3=new Student(1021,"小錢"); Student[] sArr={s1,s2,s3}; studentList.addAll(Arrays.asList(sArr)); Collections.sort(studentList); // 調(diào)用方法對(duì)學(xué)生列表進(jìn)行排序 for (Student s:studentList) { System.out.println(s.id+":"+s.name); } } }
也可以在調(diào)用sort()方法時(shí)傳入一個(gè)自定義的比較器對(duì)象Comparator,通過(guò)重寫compare()方法來(lái)實(shí)現(xiàn)兩個(gè)對(duì)象的比較。這里很明顯可以看到上面的Comparable接口是被比較對(duì)象自身實(shí)現(xiàn)的,用于自身和其他對(duì)象比較;而Comparator是第三方對(duì)象實(shí)現(xiàn)的接口,用于比較兩個(gè)對(duì)象。
// 自定義比較器類來(lái)實(shí)現(xiàn)兩個(gè)Student對(duì)象的比較 public class StudentComparator implements Comparator<Student> { @Override public int compare(Student o1, Student o2) { if (o1.id>o2.id){ // 如果大于o返回1 return 1; }else if (o1.id<o2.id){ // 小于返回-1 return -1; }else { // 等于返回0 return 0; } } } // 調(diào)用sort()方法時(shí)傳入比較器 Collections.sort(studentList,new StudentComparator());
哈希集是Set的一個(gè)實(shí)現(xiàn)類,與list不同,set中的元素是無(wú)序且不可以重復(fù)的。
和List一樣,在Set中通過(guò)add()、remove()等方法實(shí)現(xiàn)元素的增加刪除等操作。由于Set是無(wú)序的,因此沒(méi)有set()、get()方法實(shí)現(xiàn)在指定位置插入/獲取元素,在遍歷元素時(shí)通過(guò)for each、iterator來(lái)實(shí)現(xiàn),而且每次遍歷的結(jié)果順序是不確定的。
注意HashSet中的contains()方法會(huì)首先調(diào)用對(duì)象的hashCode()方法比較哈希碼,再調(diào)用equals()方法,兩個(gè)都為true才會(huì)認(rèn)為兩個(gè)對(duì)象相同。
例如通過(guò)HashSet來(lái)存儲(chǔ)學(xué)生所選課程
public class Student { public String name; public int id; public Set<Course> courses; // 用set保存學(xué)生所選課程 public Student(int id, String name) { this.name = name; this.id = id; this.courses=new HashSet<Course>(); //創(chuàng)建Hash集 } public static void main(String[] args){ Course c=new Course(1,"數(shù)據(jù)結(jié)構(gòu)"); Student s=new Student(101,"小明"); s.courses.add(c); // 向集中添加對(duì)象 for (Course course:s.courses) { // 遍歷集 System.out.println(course.name); } } }
Map以一一對(duì)應(yīng)的鍵值對(duì)<key,value>的形式儲(chǔ)存數(shù)據(jù),通過(guò)映射關(guān)系可以實(shí)現(xiàn)key快速查找value,key值不能重復(fù)。Map也支持泛型Map<K,V>,注意K,V不能是Java類,而是包裝類。
通過(guò)put(key,value)向Map中添加鍵值對(duì),get(key)通過(guò)鍵獲取值,remove(key)移除鍵。修改Map鍵值對(duì)也使用put()方法,新的鍵值對(duì)會(huì)覆蓋原有的值。通過(guò)containsKey(key)方法可以返回Map中是否包含某個(gè)key值,containsValue(value)返回Map中是否包含某個(gè)值,它通過(guò)調(diào)用對(duì)象的equals()方法比較來(lái)返回是否存在。
還可以通過(guò)keySet()、values()、entrySet()方法分別獲取Map的鍵、值、鍵值對(duì),返回的鍵值對(duì)Entry仍然可以定義泛型類型。
// 創(chuàng)建存儲(chǔ)學(xué)生類的哈希Map public Map<Integer,String> studentMap=new HashMap<Integer, String>(); public void addStudent(){ Scanner input=new Scanner(System.in); System.out.print("請(qǐng)輸入學(xué)生ID:"); int studentID=input.nextInt(); String s=studentMap.get(studentID); // 根據(jù)key值獲取對(duì)應(yīng)的value if (s!=null){ // 如果s不為空說(shuō)明該key已經(jīng)存在 System.out.println("該學(xué)生ID已存在!"); }else { System.out.print("請(qǐng)輸入姓名:"); String name=input.next(); studentMap.put(studentID,name); // 將<ID,name>鍵值對(duì)添加到Map中 } } public void showStudent(){ //通過(guò)foreach遍歷HashMap // 獲取Map的鍵值對(duì)Entry并對(duì)其泛型進(jìn)行定義 Set<Map.Entry<Integer,String>> entrySet=studentMap.entrySet(); for(Map.Entry<Integer,String> entry:entrySet){ int key= entry.getKey(); // 從Entry中獲取key String name=entry.getValue(); // 從Entry中獲取value System.out.println(key+":"+name); } } public void showStudent2(){ //通過(guò)迭代器遍歷HashMap Iterator iter = studentMap.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); Int key= entry.getKey(); String name = entry.getValue(); System.out.println(key+":"+name); } }
棧的創(chuàng)建和簡(jiǎn)單使用如下所示
Stack<Integer> st = new Stack<>(); //新建棧 st.push(3); int peek=st.peek(); //獲取棧頂元素 System.out.println(peek); int pop=st.pop(); //彈出棧頂元素 System.out.println(pop); System.out.println(st.empty()); //判斷棧是否為空
LinkedList類實(shí)現(xiàn)了Queue接口,因此我們可以把LinkedList當(dāng)成Queue來(lái)用。隊(duì)列的使用如下
Queue<Integer> queue = new LinkedList<>(); //創(chuàng)建并初始化隊(duì)列 queue.offer(1); //元素入隊(duì) queue.offer(3); queue.offer(5); for(int num:queue) //遍歷隊(duì)列 System.out.println(num); int pNum=queue.peek() //獲取第一個(gè)元素 int qNum=queue.poll(); //元素出隊(duì) System.out.println(qNum);
以上是“Java中復(fù)合數(shù)據(jù)類型怎么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。