iT邦幫忙

0

array 需宣告固定長度問題

各位大神我想問個觀念, array有必須宣告固定長度的問題, 為了簡單解決這問題,上網查找資料,很多資料顯示都是用arrayList解決這問題, 但因為兩者資料型態有所差異,需要做自動裝箱 拆箱兩個動作,但我發生一個問題, 我裝箱完想拆回來時,碰到java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
一時解不出來, 看起來一樣是一定要宣告固定長度值, 但我就是為了避開這問題曾使用arraylist, 現在好像又繞回這問題的起始點,突然腦袋卡住不知該如何解, 想問問各位大神有無其他想法

變數宣告:

int len = 0;
    int len2 = 0;
    int len3 = 0;
    int len4 = 0;
    int dataLen = 0;
    int size = 0;
 ArrayList<Byte> rawDataList = new ArrayList<>();
    byte[] bytes = new byte[rawDataList.size()];
    byte[] testBytes = new byte[rawDataList.size()];   
    

主程式碼:

 long threadStartTime;
            long threadEndTime;
            float threadSeconds = 0;

            long codeStartTime;
            long codeEndTime;
            float codeSeconds = 0;

            byte[] temp = characteristic.getValue();

            byte[] increaseCapacity = new byte[temp.length];

            System.arraycopy(temp, 0, increaseCapacity, 0, temp.length);

            Byte[] byteObjects = new Byte[increaseCapacity.length];

            int i = 0;
            // Associating Byte array values with bytes. (byte[] to Byte[])
            for (byte b : increaseCapacity) {
                byteObjects[i++] = b;  // Autoboxing.....
            }
//            System.out.println("原始資料暫存器放入資料前 "+ rawDataList);
            rawDataList.addAll(Arrays.asList(byteObjects));
//            System.out.println("原始資料暫存器放入資料後 "+ rawDataList);

            int j=0;
// Unboxing Byte values. (Byte[] to byte[])
            for(Byte b: byteObjects)
                bytes[j++] = b.byteValue();
            Process p1 = new Process();
            size = bytes.length;

            codeStartTime = System.currentTimeMillis();
            for (int m = 0; m < size; m++) {
                if (m + 1 < size && m + 2 < size && m + 3 < size) {
                    if ((bytes[m] & 0xFF) == 2 && (bytes[m+1] & 0xFF) == 1 && (bytes[m+2] & 0xFF) == 4 && (bytes[m+3] & 0xFF) == 3) {
//                        System.out.println("跑檢查標頭判斷後原始資料暫存器資料 "+ rawDataList);
                        len = (bytes[m+8] & 0xFF);
                        len2 = (bytes[m+9] & 0xFF);
                        len3 = (bytes[m+10] & 0xFF);
                        len4 = (bytes[m+11] & 0xFF);

                        dataLen = len + len2 + len3 + len4 - 4;

                        if (m+dataLen+12 < size && m+dataLen+13 < size && m+dataLen+14 < size && m+dataLen+15 < size) {
                            if (bytes[m+dataLen+12] == -1 && bytes[m+dataLen+13] == -1 && bytes[m+dataLen+14] == -1 && bytes[m+dataLen+15] == -1)
                            {
//                                System.out.println("跑檢查標尾判斷後原始資料暫存器資料 "+ rawDataList);
                                threadStartTime = System.currentTimeMillis();
                                p1.run();
                                threadEndTime = System.currentTimeMillis();
                                threadSeconds = (threadEndTime - threadStartTime) / 1000F;

                            }
                        }

                    }
                }
            }
            codeEndTime = System.currentTimeMillis();
            codeSeconds = (codeEndTime - codeStartTime) / 1000F;

//            if( codeSeconds > threadSeconds){
//                System.out.println("狀況正常 ");
//                System.out.println("執行緒共花 "+Float.toString(threadSeconds)+   " seconds. ");
//                System.out.println("整段程式共花 "+Float.toString(codeSeconds)+   " seconds. ");
//            }
//
//            else{
//                System.out.println("狀況不對 有問題 ");
//                System.out.println("執行緒共花 "+Float.toString(threadSeconds)+   " seconds. ");
//                System.out.println("整段程式共花 "+Float.toString(codeSeconds)+   " seconds. ");
//            }

        }

執行緒類別1:

public class Process implements Runnable {
        @Override
        public void run() {
            dataProcess testProcess = new dataProcess();
            testProcess.findHeadTail(bytes);
        }
    }

執行緒類別2:

class dataProcess {
        public synchronized void findHeadTail(byte[] array) {
            int length = 0;
            int length2 = 0;
            int length3 = 0;
            int length4 = 0;
            int dataLength = 0;
            int size = array.length;

            for (int k = 0; k < size; k++) {
                if (k + 1 < size && k + 2 < size && k + 3 < size) {
                    if ((array[k] & 0xFF) == 2 && (array[k+1] & 0xFF) == 1 && (array[k+2] & 0xFF) == 4 && (array[k+3] & 0xFF) == 3) {
//                        System.out.println("跑尋找標頭判斷後原始資料暫存器資料 "+ rawDataList);
                        length = (array[k+8] & 0xFF);
                        length2 = (array[k+9] & 0xFF);
                        length3 = (array[k+10] & 0xFF);
                        length4 = (array[k+11] & 0xFF);

                        dataLength = length + length2 + length3 + length4 - 4;

                        if (k+dataLength+12 < size && k+dataLength+13 < size && k+dataLength+14 < size && k+dataLength+15 < size) {
                            if (array[k+dataLength+12] == -1 && array[k+dataLength+13] == -1 && array[k+dataLength+14] == -1 && array[k+dataLength+15] == -1)
                            {
//                                System.out.println("跑尋找標尾判斷後原始資料暫存器資料 "+ rawDataList);
//                                System.out.println("正確資料暫存器擷取資料前 "+ realDataList);
//                                tailCount++;
//                                System.out.println(tailCount);
                                for (int p=k+12; p<k+12+dataLength; p++){
                                    testBytes[p] = bytes[p] ;
//                                    realDataList.add(rawDataList.get(p));
                                }
//                                System.out.println("正確資料暫存器擷取資料後 "+ realDataList);

                                StringBuilder stringBuilder = new StringBuilder(testBytes.length);
                                for (byte byteChar : testBytes)
                                    stringBuilder.append(String.format("%02X ", byteChar));
                                System.out.println(stringBuilder.toString());
//                                printCount++;
//                                System.out.println(printCount);
//                                realDataList.clear();
                            }
                        }
                    }
                }
            }

        }
    }

輸出:
https://ithelp.ithome.com.tw/upload/images/20211115/20143658iKihlY8Wn3.png

GHH iT邦新手 4 級 ‧ 2021-11-15 15:29:16 檢舉
IndexOutOfBounds 跟是不是固定長度無關,純粹是你取值的時候 index 超過陣列長度

1 個回答

0
小魚
iT邦大師 1 級 ‧ 2021-11-15 15:18:00

Java不熟,
不過這一段看起來,

ArrayList<Byte> rawDataList = new ArrayList<>();
byte[] bytes = new byte[rawDataList.size()];
byte[] testBytes = new byte[rawDataList.size()];   

因為剛呼叫的時候size是0,
0的話應該不能new一個byte的array,
所以會跳錯誤.

我要發表回答

立即登入回答