Java中的復(fù)合數(shù)據(jù)類型
1、Java字符串
在 Java 中字符串被作為 String 類型的對象處理。 String 類位于 java.lang 包中,默認(rèn)情況下該包自動(dòng)導(dǎo)入。
String對象創(chuàng)建后不會(huì)被修改,當(dāng)我們修改某個(gè)字符串對象實(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)前字符串的長度 str.indexOf(int ch) //查找ch字符在該字符串中第一次出現(xiàn)的位置,若無返回-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) //將該字符串與指定對象比較,返回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類來保存,可以通過append、replace等方法對字符串進(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
}
}
通過String.valueOf()可以將其他類型數(shù)據(jù)轉(zhuǎn)化為字符串。
char[] arr={'a', 'd', 'e'};
String s=String.valueOf(arr);
2、Java中的包裝類
Java中的基本數(shù)據(jù)類型如int、double等都不具有對象的特性,為了像其他對象一樣擁有自己的方法,Java為每個(gè)基本數(shù)據(jù)類型提供了包裝類,像對象那樣來操作基本數(shù)據(jù)類型。包裝類的基本方法用于實(shí)現(xiàn)類型之間的相互轉(zhuǎn)換。
Java包裝類可以自動(dòng)裝箱/拆箱,即通過=運(yùn)算符自動(dòng)完成基本類型和包裝類之間的類型轉(zhuǎn)換。

// 定義int類型變量,值為86
int score1 = 86;
// 使用int創(chuàng)建Integer包裝類對象,手動(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)換:

通過Integer.MAX_VALUE可以獲得最大整數(shù)值
使用 java.util 包中的 Date 類可以創(chuàng)建時(shí)間對象,使用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í)間對象Date轉(zhuǎn)換為指定的格式的字符串,反之parse()方法可以將普通字符串轉(zhuǎn)化為Date對象。

java.util.Calendar 類可以更加方便地進(jìn)行時(shí)間的處理,通過調(diào)用 getInstance() 靜態(tài)方法獲取一個(gè) Calendar 對象,默認(rèn)代表當(dāng)前時(shí)間,可以通過c.getTime()將其轉(zhuǎn)化為Date對象。Calendar對象的更多方法如下

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ù)
3、Java容器
在各種基本數(shù)據(jù)類型的基礎(chǔ)上,Java使用集合類當(dāng)作容器來儲(chǔ)存具有相同屬性的對象。通過集合類組織數(shù)據(jù)可以實(shí)現(xiàn)對特定數(shù)據(jù)的快速插入、刪除與查詢操作。而且與數(shù)組相比,集合的長度靈活可變,而且查找方式也不只有下標(biāo)一種。Java中常見的集合類分為兩個(gè)接口Collection和Map,其中Collection有三個(gè)子接口鏈表List、隊(duì)列Queue、集Set,List常見的實(shí)現(xiàn)類為數(shù)組序列ArrayList,Queue實(shí)現(xiàn)類為LinkedList稱為鏈表,Set實(shí)現(xiàn)類為哈希集。Collection中按照一個(gè)一個(gè)對象來存儲(chǔ)數(shù)據(jù),Map中按照鍵值對<key,value>來存儲(chǔ)數(shù)據(jù)。
Collection接口規(guī)定了ArrayList、Set等具體實(shí)現(xiàn)類的接口方法,例如它們都使用add()方法來添加元素,因此一些方法名在各個(gè)類實(shí)現(xiàn)中是通用的。

ArrayList
ArrayList是類似于數(shù)組的容器,將對象儲(chǔ)存進(jìn)ArrayList之中便于組織和管理。通過add()方法可以將單個(gè)對象插入列表,addAll()可以將多個(gè)對象組成的子列表插入父列表中,插入時(shí)可以指定插入的位置,可以通過Arrays.asList()將數(shù)組轉(zhuǎn)化為列表,通過toArray()方法可以將列表轉(zhuǎn)為Object[]數(shù)組,可以向其中傳入泛型參數(shù)從而返回特定類型的數(shù)組。
需要注意的是通過Arrays.asList()轉(zhuǎn)化成的List長度是固定的,不能進(jìn)行add()操作,會(huì)報(bào)錯(cuò);我們可以將其作為子列表添加到一個(gè)新的List列表,然后再進(jìn)行插入操作。
例如向列表courseList中插入Course對象:
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ù)組列表中添加對象
courseList.add(0,c2); // 向指定位置添加對象
courseList.addAll(Arrays.asList(cArr)); // 向列表中添加子列表,前加數(shù)字表示插入位置
Course tmp=(Course)courseList.get(0); // 從列表中取出對象
Course[] courseArr=courseList.toArray(new Course[courseList.size()]); // 轉(zhuǎn)換為特定類型的數(shù)組
}
特別地,int[]與List<Integer>之間無法直接使用asList()/toArray()方法進(jìn)行互相轉(zhuǎn)換,可以經(jīng)過如下流操作,或者遍歷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();
通過size()方法可以獲取列表長度,通過get()方法可以獲取指定位置的對象,進(jìn)而通過for循環(huán)遍歷每個(gè)對象,也可以使用for each的方式遍歷每個(gè)元素。還可以通過迭代器實(shí)現(xiàn)對每個(gè)對象的訪問。值得注意的是,每個(gè)對象在列表中都是以O(shè)bject對象的方式儲(chǔ)存的,因此在取出之后需要通過強(qiáng)制類型轉(zhuǎn)換為原來的對象類型,例如(Course)轉(zhuǎn)為Course類的對象
public void showCourse(){
int listLength=courseList.size(); // 獲取列表長度
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);
}
}
通過set()方法對列表指定位置的元素進(jìn)行修改。通過remove()方法移除指定位置或者指定對象。通過removeAll()刪除父列表中包含的所有子列表中的元素,通過clear()可以清空列表。
public void modifyCourse(){
courseList.set(2,new Course(5,"離散數(shù)學(xué)")); // 修改2位置上的對象
}
public void removeCourse(){
courseList.remove(3); // 刪除3位置上的對象
Course c1= (Course) courseList.get(1);
Course c2=(Course) courseList.get(2);
courseList.remove(c1); // 刪除指定對象
Course[] cArr={c1,c2};
courseList.removeAll(Arrays.asList(cArr)); // 刪除courseList中所包含的cArr的元素
}
通過contains()、containsAll()方法判斷List是否包含某個(gè)或者某幾個(gè)對象,其實(shí)現(xiàn)原理是遍歷List中的每個(gè)對象調(diào)用其equals()方法和目標(biāo)對象進(jìn)行比較,如果存在返回true,否則返回false。因此我們可以重寫Course類的equals()方法,進(jìn)而調(diào)用contains()方法判斷List中是否包含指定Course對象。類似地indexOf()方法可以通過調(diào)用equals()找到元素在List中第一次出現(xiàn)的位置。
// 重寫Course類的equals()方法
public boolean equals(Object o) {
if (this == o) return true; // 如果兩個(gè)對象的地址相同,肯定相同
if (!(o instanceof Course)) return false;
Course course = (Course) o;
return id == course.id && // 判斷兩個(gè)Course對象的id和name相同
name.equals(course.name);
}
// 在CourseList中調(diào)用contains()判讀是否包含某個(gè)對象
public void containCourse(){
Course nc=new Course(5,"數(shù)據(jù)結(jié)構(gòu)");
if(courseList.contains(nc)) { // 判斷List中是否包含Course對象nc
int index = courseList.indexOf(nc); // 獲取元素在List中的位置
System.out.println("列表中包含該課程,位置:" + index);
}
}
之前提到集合中存放的都是對象的引用(Object),每次存入時(shí)集合會(huì)忽略對象的具體類型,有時(shí)存入其他類型對象則會(huì)在運(yùn)行時(shí)出錯(cuò),而且每次取出時(shí)則需要進(jìn)行類型的強(qiáng)制轉(zhuǎn)換還原回來??梢允褂?strong>泛型規(guī)定某個(gè)集合只能存放特定類型或者其子類型的對象,這樣就會(huì)在編譯期間進(jìn)行類型檢查,而且在取出時(shí)可以直接返回特定類型的對象。注意泛型不能用于基本數(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類型的對象,報(bào)錯(cuò)
Course c2=courseList.get(0); // 可以直接取出為Course類型對象
System.out.println(c2.name);
}
通過集合的工具類Collections.sort()方法可以實(shí)現(xiàn)對List對象的排序,其實(shí)現(xiàn)的原理是調(diào)用每個(gè)元素的compareTo()方法實(shí)現(xiàn)對象之間的比較進(jìn)而排序。因此每個(gè)對象必須是可比較的類型,即必須實(shí)現(xiàn)了Comparable 接口的對象,如下所示首先定義可比較類Student,再定義學(xué)生列表studentLis添加學(xué)生對象后,調(diào)用Collections.sort()方法對列表進(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大小對學(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)用方法對學(xué)生列表進(jìn)行排序
for (Student s:studentList) {
System.out.println(s.id+":"+s.name);
}
}
}
也可以在調(diào)用sort()方法時(shí)傳入一個(gè)自定義的比較器對象Comparator,通過重寫compare()方法來實(shí)現(xiàn)兩個(gè)對象的比較。這里很明顯可以看到上面的Comparable接口是被比較對象自身實(shí)現(xiàn)的,用于自身和其他對象比較;而Comparator是第三方對象實(shí)現(xiàn)的接口,用于比較兩個(gè)對象。
// 自定義比較器類來實(shí)現(xiàn)兩個(gè)Student對象的比較
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());
HashSet
哈希集是Set的一個(gè)實(shí)現(xiàn)類,與list不同,set中的元素是無序且不可以重復(fù)的。
和List一樣,在Set中通過add()、remove()等方法實(shí)現(xiàn)元素的增加刪除等操作。由于Set是無序的,因此沒有set()、get()方法實(shí)現(xiàn)在指定位置插入/獲取元素,在遍歷元素時(shí)通過for each、iterator來實(shí)現(xiàn),而且每次遍歷的結(jié)果順序是不確定的。
注意HashSet中的contains()方法會(huì)首先調(diào)用對象的hashCode()方法比較哈希碼,再調(diào)用equals()方法,兩個(gè)都為true才會(huì)認(rèn)為兩個(gè)對象相同。
例如通過HashSet來存儲(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); // 向集中添加對象
for (Course course:s.courses) { // 遍歷集
System.out.println(course.name);
}
}
}
HashMap
Map以一一對應(yīng)的鍵值對<key,value>的形式儲(chǔ)存數(shù)據(jù),通過映射關(guān)系可以實(shí)現(xiàn)key快速查找value,key值不能重復(fù)。Map也支持泛型Map<K,V>,注意K,V不能是Java類,而是包裝類。
通過put(key,value)向Map中添加鍵值對,get(key)通過鍵獲取值,remove(key)移除鍵。修改Map鍵值對也使用put()方法,新的鍵值對會(huì)覆蓋原有的值。通過containsKey(key)方法可以返回Map中是否包含某個(gè)key值,containsValue(value)返回Map中是否包含某個(gè)值,它通過調(diào)用對象的equals()方法比較來返回是否存在。
還可以通過keySet()、values()、entrySet()方法分別獲取Map的鍵、值、鍵值對,返回的鍵值對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("請輸入學(xué)生ID:");
int studentID=input.nextInt();
String s=studentMap.get(studentID); // 根據(jù)key值獲取對應(yīng)的value
if (s!=null){ // 如果s不為空說明該key已經(jīng)存在
System.out.println("該學(xué)生ID已存在!");
}else {
System.out.print("請輸入姓名:");
String name=input.next();
studentMap.put(studentID,name); // 將<ID,name>鍵值對添加到Map中
}
}
public void showStudent(){ //通過foreach遍歷HashMap
// 獲取Map的鍵值對Entry并對其泛型進(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(){ //通過迭代器遍歷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);
}
}
4、工具類
Stack
棧的創(chuàng)建和簡單使用如下所示
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()); //判斷棧是否為空
Queue
LinkedList類實(shí)現(xiàn)了Queue接口,因此我們可以把LinkedList當(dāng)成Queue來用。隊(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);
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringAOP實(shí)現(xiàn)自定義接口權(quán)限控制
本文主要介紹了SpringAOP實(shí)現(xiàn)自定義接口權(quán)限控制,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-11-11
Java數(shù)據(jù)結(jié)構(gòu)最清晰圖解二叉樹前 中 后序遍歷
樹是一種重要的非線性數(shù)據(jù)結(jié)構(gòu),直觀地看,它是數(shù)據(jù)元素(在樹中稱為結(jié)點(diǎn))按分支關(guān)系組織起來的結(jié)構(gòu),很象自然界中的樹那樣。樹結(jié)構(gòu)在客觀世界中廣泛存在,如人類社會(huì)的族譜和各種社會(huì)組織機(jī)構(gòu)都可用樹形象表示2022-01-01
新手入門學(xué)習(xí)Spring Freemarker教程解析
這篇文章主要介紹了新手入門學(xué)習(xí)Freemarker教程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10
Java實(shí)現(xiàn)跨服務(wù)器上傳文件功能
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)跨服務(wù)器上傳文件功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
Java拖曳鼠標(biāo)實(shí)現(xiàn)畫線功能的方法
這篇文章主要介紹了Java拖曳鼠標(biāo)實(shí)現(xiàn)畫線功能的方法,需要的朋友可以參考下2014-07-07
SpringBoot整合thymeleaf 報(bào)錯(cuò)的解決方案
這篇文章主要介紹了SpringBoot整合thymeleaf 報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08

