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

Java中List集合數(shù)據(jù)修改方式

 更新時間:2023年02月07日 17:02:45   作者:single_cong  
這篇文章主要介紹了Java中List集合數(shù)據(jù)修改方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

Java中List集合數(shù)據(jù)修改

先說寫這篇文章的原因

我被提供了一個需求,Excel表格數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫,按照常理而言是很簡單的,但是這個需求不那么簡單,Excel表格里面的字段和數(shù)據(jù)庫不統(tǒng)一,甚至多與實體類的屬性數(shù)量,而且要實現(xiàn)用戶自由選擇Excel表格某列對應(yīng)數(shù)據(jù)庫某個字段,聽到這個需求我真的是被整懵逼了?。?!

先說一下我的思路,首先,我個人感覺不可能將Excel表格全部讀出來(數(shù)據(jù)類型無法統(tǒng)一;不知道列數(shù)量;選擇的列比較少的話,效率慢死;)所以我的想法是按照列讀取數(shù)據(jù)(我認(rèn)為Excel數(shù)據(jù)讀取都是要遍歷一遍二維數(shù)組,按行按列于操作Excel效率沒什么區(qū)別)

為了方便,我寫的讀取Excel的工具類返回的是Map類型數(shù)據(jù),map里面放入List集合,通過返回的List集合獲取數(shù)據(jù),這樣我就可以獲取很多類型的數(shù)據(jù)而不必局限于返回值類型

這里是我循環(huán)賦值的語句

public Map<String, Object> importSQL(@RequestBody String c, HttpServletRequest request) throws Exception {
? ? java.util.Map<String, Object> map = new HashMap<>();
? ? java.util.Map<String, Object> poiMap = new HashMap<>();
? ? // 對Excel表格操作的工具類
? ? PoiExcel poiExcel = new PoiExcel();
? ? // 保存從Excel讀取出來信息
? ? List<Attendance> attList = new ArrayList<Attendance>();
? ? List<String> string = new ArrayList<String>();
? ? Attendance att = new Attendance();
? ? try {
? ? ? ? List<Relation> relationList = new ArrayList<Relation>();
? ? ? ? JSONObject strj = new JSONObject(c);
? ? ? ? // 獲取讀取Excel表格開始行數(shù)
? ? ? ? int startRow = strj.getInt("start");
? ? ? ? // 獲取用戶自定義匹配數(shù)據(jù)
? ? ? ? String json = strj.getJSONArray("matchData").toString();
? ? ? ? // 獲取用戶上傳excel表格保存路徑
? ? ? ? String filePath = strj.getString("filePath");
? ? ? ? filePath = "1230.xls";
? ? ? ? // 將用戶自定義匹配數(shù)據(jù)放入relationList中,便于取值
? ? ? ? relationList = com.alibaba.fastjson.JSONArray.parseArray(json, Relation.class);
? ? ? ? /**
? ? ? ? ?* 測試使用
? ? ? ? ?*/
? ? ? ? for (int i = 0; i < relationList.size(); i++) {
? ? ? ? ? ? System.out.println("第"+i+"次執(zhí)行");
? ? ? ? ? ? /**
? ? ? ? ? ? ?* 匹配查詢 filePath:文件名字 startRow:開始查詢行數(shù)
? ? ? ? ? ? ?* relationList.get(i).getColumnNum():查詢列值
? ? ? ? ? ? ?* 返回map類型數(shù)據(jù),數(shù)據(jù)類型多樣,統(tǒng)一返回值 返回值是List類型數(shù)據(jù),工具類中暫時只有一個String類型,測試使用
? ? ? ? ? ? ?*/
? ? ? ? ? ? string = (List<String>) poiExcel.ExcelRead(filePath, startRow, relationList.get(i).getColumnNum())
? ? ? ? ? ? ? ? ? ? .get("list");
? ? ? ? ? ? // 初始化集合
? ? ? ? ? ? if (i == 0) {
? ? ? ? ? ? ? ? for (int a = 0; a < string.size(); a++) {
? ? ? ? ? ? ? ? ? ? attList.add(att);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? if (relationList.get(i).getDescribe().equals("學(xué)號")) {
? ? ? ? ? ? ? ? System.out.println("學(xué)號");
? ? ? ? ? ? ? ? // 循環(huán)賦值
? ? ? ? ? ? ? ? for (int j = 0; j < string.size(); j++) {
? ? ? ? ? ? ? ? ? ? attList.get(j).setStuid(string.get(j));
? ? ? ? ? ? ? ? }
? ? ? ? ? ? } else if (relationList.get(i).getDescribe().equals("姓名")) {
? ? ? ? ? ? ? ? System.out.println("姓名");
? ? ? ? ? ? ? ? // 循環(huán)賦值
? ? ? ? ? ? ? ? for (int j = 0; j < string.size(); j++) {
? ? ? ? ? ? ? ? ? ? attList.get(j).setName(string.get(j));
? ? ? ? ? ? ? ? }
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? System.out.println("分?jǐn)?shù)");
? ? ? ? ? ? ? ? for (int j = 0; j < string.size(); j++) {
? ? ? ? ? ? ? ? ? ? attList.get(j).setScore(Integer.parseInt(string.get(j)));
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? } catch (Exception e) {
? ? ? ? System.out.println(e);
? ? }
? ? /**
? ? ?* 以上為for循環(huán)遍歷Excel表格數(shù)據(jù),以下為測試輸出,遍歷是否正確
? ? ?*/
? ? for (int x = 0; x < attList.size(); x++) {
? ? ? ? System.out.println("讀取Excel表格信息為:" + attList.get(x).toString());
? ? }
? ? return map;
}

我的想法是先初始化集合,確定集合size和集合屬性,但是突然出現(xiàn)一個問題就是我遍歷出來的數(shù)據(jù)在循環(huán)賦值的時候attList里面的屬性全部變成最新一次的屬性,然后我就debug調(diào)試,發(fā)現(xiàn)每次賦值前面對應(yīng)的值也都會更改,當(dāng)時腦子里面就冒出了一個念頭:值類型和引用類型傳遞?。?!于是,我做了如下更改:

? ? if (i == 0) {
? ? ? ? for (int a = 0; a < string.size(); a++) {
? ? ? ? ? ? Attendance att = new Attendance();
? ? ? ? ? ? attList.add(att);
? ? ? ? }
? ? }

將new 對象這句話放到for循環(huán)里面

運行之后值就對了,唉,開發(fā)經(jīng)驗太少,竟然被這種問題困擾了一天

下面是我百度的值類型和引用類型區(qū)別:

引用類型表示你操作的數(shù)據(jù)是同一個,也就是說當(dāng)你傳一個參數(shù)給另一個方法時,你在另一個方法中改變這個變量的值,那么調(diào)用這個方法是傳入的變量的值也將改變.

值類型表示復(fù)制一個當(dāng)前變量傳給方法,當(dāng)你在這個方法中改變這個變量的值時,最初生命的變量的值不會變.

引用傳遞:傳的是地址,就是將實參的地址傳遞給形參,形參改變了,實參當(dāng)然被改變了,因為他們指向相同的地址。

最后,一定要記住,當(dāng)引用一個集合的時候,集合里面有n個對象,這個時候肯定要new n對象,否則,這些對象是引用的同一個?。。?!

Java中List集合的介紹

List 是什么

JavaList集合是指由JavaList接口以及List接口的所有實現(xiàn)類組成的集合。

List集合中的元素允許重復(fù),各元素的順序放是對象插入的順序. 類似Java中的數(shù)組,用戶可通過使用索引(元素在集合中的位置)來訪問集合中的元素.

1.Java集合介紹

Java集合就像一個容器,可以存儲任何類型的數(shù)據(jù),也可以結(jié)合泛型來存儲具體的類型對象。在程序運行時,Java集合可以動態(tài)的進(jìn)行擴展,隨著元素的增加而擴大。在Java中,集合類通常存在于java.util包中。

Java集合主要由2大體系構(gòu)成,分別是Collection體系和Map體系,其中Collection和Map分別是2大體系中的頂層接口。

Collection主要有三個子接口,分別為List(列表)、Set(集)、Queue(隊列)。其中,List、Queue中的元素有序可重復(fù),而Set中的元素?zé)o序不可重復(fù)。

List中主要有ArrayList、LinkedList兩個實現(xiàn)類;Set中則是有HashSet實現(xiàn)類;而Queue是在JDK1.5后才出現(xiàn)的新集合,主要以數(shù)組和鏈表兩種形式存在。

Map同屬于java.util包中,是集合的一部分,但與Collection是相互獨立的,沒有任何關(guān)系。Map中都是以key-value的形式存在,其中key必須唯一,主要有HashMap、HashTable、treeMap三個實現(xiàn)類。

2.List介紹

Collection中,List集合是有序的,可對其中每個元素的插入位置進(jìn)行精確地控制,可以通過索引來訪問元素,遍歷元素。

在List集合中,我們常用到ArrayListLinkedList這兩個類

2.1 ArrayList集合

  • ArrayList底層通過數(shù)組實現(xiàn),隨著元素的增加而動態(tài)擴容。
  • ArrayList是Java集合框架中使用最多的一個類,是一個數(shù)組隊列,線程不安全集合。它繼承于AbstractList,實現(xiàn)了List, RandomAccess, Cloneable, Serializable接口。
  • ArrayList實現(xiàn)List,得到了List集合框架基礎(chǔ)功能;
  • ArrayList實現(xiàn)RandomAccess,獲得了快速隨機訪問存儲元素的功能,RandomAccess是一個標(biāo)記接口,沒有任何方法;
  • ArrayList實現(xiàn)Cloneable,得到了clone()方法,可以實現(xiàn)克隆功能;
  • ArrayList實現(xiàn)Serializable,表示可以被序列化,通過序列化去傳輸,典型的應(yīng)用就是hessian協(xié)議。

ArrayList集合的特點:

  • 容量不固定,隨著容量的增加而動態(tài)擴容(閾值基本不會達(dá)到)
  • 有序集合(插入的順序==輸出的順序)
  • 插入的元素可以為null
  • 增刪改查效率更高(相對于LinkedList來說)
  • 線程不安全

ArrayList的底層數(shù)據(jù)結(jié)構(gòu):

ArrayList的底層數(shù)據(jù)結(jié)構(gòu)

2.2 LinkedList集合

  • LinkedList底層通過鏈表來實現(xiàn),隨著元素的增加不斷向鏈表的后端增加節(jié)點。
  • LinkedList是一個雙向鏈表,每一個節(jié)點都擁有指向前后節(jié)點的引用。相比于ArrayList來說,LinkedList的隨機訪問效率更低。它繼承AbstractSequentialList,實現(xiàn)了List, Deque, Cloneable, Serializable接口。
  • LinkedList實現(xiàn)List,得到了List集合框架基礎(chǔ)功能;
  • LinkedList實現(xiàn)Deque,Deque 是一個雙向隊列,也就是既可以先入先出,又可以先入后出,說簡單點就是既可以在頭部添加元素,也可以在尾部添加元素;
  • LinkedList實現(xiàn)Cloneable,得到了clone()方法,可以實現(xiàn)克隆功能;
  • LinkedList實現(xiàn)Serializable,表示可以被序列化,通過序列化去傳輸,典型的應(yīng)用就是hessian協(xié)議。

LinkedList集合的底層數(shù)據(jù)結(jié)構(gòu):

LinkedList集合的底層數(shù)據(jù)結(jié)構(gòu)

3.List常用方法

A:添加功能
boolean add(E e):向集合中添加一個元素
void add(int index, E element):在指定位置添加元素
boolean addAll(Collection<? extends E> c):向集合中添加一個集合的元素。

B:刪除功能
void clear():刪除集合中的所有元素
E remove(int index):根據(jù)指定索引刪除元素,并把刪除的元素返回
boolean remove(Object o):從集合中刪除指定的元素
boolean removeAll(Collection<?> c):從集合中刪除一個指定的集合元素。

C:修改功能
E set(int index, E element):把指定索引位置的元素修改為指定的值,返回修改前的值。

D:獲取功能
E get(int index):獲取指定位置的元素
Iterator iterator():就是用來獲取集合中每一個元素。

E:判斷功能
boolean isEmpty():判斷集合是否為空。
boolean contains(Object o):判斷集合中是否存在指定的元素。
boolean containsAll(Collection<?> c):判斷集合中是否存在指定的一個集合中的元素。

F:長度功能
int size():獲取集合中的元素個數(shù)

G:把集合轉(zhuǎn)換成數(shù)組
Object[] toArray():把集合變成數(shù)組。

3.1 ArrayList 基本操作

public class ArrayListTest {
    public static void main(String[] agrs){
        //創(chuàng)建ArrayList集合:
        List<String> list = new ArrayList<String>();
        System.out.println("ArrayList集合初始化容量:"+list.size());
		// ArrayList集合初始化容量:0
        
        //添加功能:
        list.add("Hello");
        list.add("world");
        list.add(2,"!");
        System.out.println("ArrayList當(dāng)前容量:"+list.size());
        // ArrayList當(dāng)前容量:3

        //修改功能:
        list.set(0,"my");
        list.set(1,"name");
        System.out.println("ArrayList當(dāng)前內(nèi)容:"+list.toString());
        // ArrayList當(dāng)前內(nèi)容:[my, name, !]

        //獲取功能:
        String element = list.get(0);
        System.out.println(element);
        // my

        //迭代器遍歷集合:(ArrayList實際的跌倒器是Itr對象)
        Iterator<String> iterator =  list.iterator();
        while(iterator.hasNext()){
            String next = iterator.next();
            System.out.println(next);
        }
        /**  
        	my
            name
            !
        */

        //for循環(huán)迭代集合:
        for(String str:list){
            System.out.println(str);
        }
        /**  
        	my
            name
            !
        */

        //判斷功能:
        boolean isEmpty = list.isEmpty();
        boolean isContain = list.contains("my");

        //長度功能:
        int size = list.size();

        //把集合轉(zhuǎn)換成數(shù)組:
        String[] strArray = list.toArray(new String[]{});

        //刪除功能:
        list.remove(0);
        list.remove("world");
        list.clear();
        System.out.println("ArrayList當(dāng)前容量:"+list.size());
        // ArrayList當(dāng)前容量:0
    }
}

3.2 LinkedList 基本操作

public class LinkedListTest {
    public static void main(String[] agrs){
        List<String> linkedList = new LinkedList<String>();
        System.out.println("LinkedList初始容量:"+linkedList.size());
        // LinkedList初始容量:0

        //添加功能:
        linkedList.add("my");
        linkedList.add("name");
        linkedList.add("is");
        linkedList.add("jiaboyan");
        System.out.println("LinkedList當(dāng)前容量:"+ linkedList.size());
        // LinkedList當(dāng)前容量:4

        //修改功能:
        linkedList.set(0,"hello");
        linkedList.set(1,"world");
        System.out.println("LinkedList當(dāng)前內(nèi)容:"+ linkedList.toString());
        // LinkedList當(dāng)前內(nèi)容:[hello, world, is, jiaboyan]

        //獲取功能:
        String element = linkedList.get(0);
        System.out.println(element);
        // hello

        //遍歷集合:(LinkedList實際的迭代器是ListItr對象)
        Iterator<String> iterator =  linkedList.iterator();
        while(iterator.hasNext()){
            String next = iterator.next();
            System.out.println(next);
        }
        /**
        	hello
            world
            is
            jiaboyan
        */
        
        //for循環(huán)迭代集合:
        for(String str:linkedList){
            System.out.println(str);
        }
        /**
        	hello
            world
            is
            jiaboyan
        */

        //判斷功能:
        boolean isEmpty = linkedList.isEmpty();
        boolean isContains = linkedList.contains("jiaboyan");

        //長度功能:
        int size = linkedList.size();

        //刪除功能:
        linkedList.remove(0);
        linkedList.remove("jiaboyan");
        linkedList.clear();
        System.out.println("LinkedList當(dāng)前容量:" + linkedList.size());
        // LinkedList當(dāng)前容量:0
    }
}

4.ArrayList和LinkedList比較

元素新增性能比較

網(wǎng)上很多說的是,在做新增操作時,ArrayList的效率遠(yuǎn)不如LinkedList,因為Arraylist底層時數(shù)組實現(xiàn)的,在動態(tài)擴容時,性能會有所損耗,而LinkedList不存在數(shù)組擴容機制,所以LinkedList的新增性能較好。究竟時哪個好呢,我們用實踐得到結(jié)果。

public class ListTest{
    // 迭代次數(shù)
    public static int ITERATION_NUM = 100000;

    public static void main(String[] args) {
        try{
            insertPerformanceCompare();
        }catch (Exception e){}
    }

    //新增性能比較:
    public static void insertPerformanceCompare() throws InterruptedException {
        Thread.sleep(5000);

        long start = System.nanoTime();
        List<Integer> linkedList = new LinkedList<Integer>();
        for (int x = 0; x < ITERATION_NUM; x++) {
            linkedList.add(x);
        }
        long end = System.nanoTime();
        System.out.println("LinkedList獲取測試開始 " + (end - start));

        start = System.nanoTime();
        List<Integer> arrayList = new ArrayList<Integer>();
        for (int x = 0; x < ITERATION_NUM; x++) {
            arrayList.add(x);
        }
        end = System.nanoTime();
        System.out.println("ArrayList獲取測試開始 " + (end - start));
    }
}

測試結(jié)果:

第一次:
LinkedList新增測試開始 10873720
ArrayList新增測試開始 5535277
第二次:
LinkedList新增測試開始 13097503
ArrayList新增測試開始 6046139
第三次:
LinkedList新增測試開始 12004669
ArrayList新增測試開始 6509783

結(jié)果與預(yù)想的有些不太一樣,ArrayList的新增性能并不低。

原因:

可能是經(jīng)過JDK近幾年的更新發(fā)展,對于數(shù)組復(fù)制的實現(xiàn)進(jìn)行了優(yōu)化,以至于ArrayList的性能也得到了提高。

元素獲取比較

由于LinkedList是鏈表結(jié)構(gòu),沒有角標(biāo)的概念,沒有實現(xiàn)RandomAccess接口,不具備隨機元素訪問功能,所以在get方面表現(xiàn)的差強人意,ArrayList再一次完勝。

public class ListTest {
    //迭代次數(shù),集合大?。?
    public static int ITERATION_NUM = 100000;

    public static void main(String[] agrs) {
       try{
            getPerformanceCompare();
        }catch (Exception e){}
    }

    //獲取性能比較:
    public static void getPerformanceCompare()throws InterruptedException {
        Thread.sleep(5000);

        //填充ArrayList集合:
        List<Integer> arrayList = new ArrayList<Integer>();
        for (int x = 0; x < ITERATION_NUM; x++) {
            arrayList.add(x);
        }

        //填充LinkedList集合:
        List<Integer> linkedList = new LinkedList<Integer>();
        for (int x = 0; x < ITERATION_NUM; x++) {
            linkedList.add(x);
        }

        //創(chuàng)建隨機數(shù)對象:
        Random random = new Random();

        long start = System.nanoTime();
        for (int x = 0; x < ITERATION_NUM; x++) {
            int j = random.nextInt(x + 1);
            int k = linkedList.get(j);
        }
        long end = System.nanoTime();
        System.out.println("LinkedList獲取測試開始 " + (end - start));

        start = System.nanoTime();
        for (int x = 0; x < ITERATION_NUM; x++) {
            int j = random.nextInt(x + 1);
            int k = arrayList.get(j);
        }
        end = System.nanoTime();
        System.out.println("ArrayList獲取測試開始 " + (end - start));
    }
}

測試結(jié)果:

第一次:
LinkedList獲取測試開始 8190063123
ArrayList獲取測試開始 8590205
第二次:
LinkedList獲取測試開始 8100623160
ArrayList獲取測試開始 11948919
第三次:
LinkedList獲取測試開始 8237722833
ArrayList獲取測試開始 6333427

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論