0

I am trying to concatenate two arrays to add labels to the columns of a numeric array and also to add a total after the last row of the array. I have found some code on another Stack Overflow thread How can I concatenate two arrays in Java?. But I get an error

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [[Ljava.lang.Object;

Here is my code

public void getpdf(double[][] pricelist, ArrayList<Piece> in) {
    PDDocument doc = new PDDocument();
    PDPage page = new PDPage();
    doc.addPage( page );
    try {
            PDPageContentStream contentStream =
                            new PDPageContentStream(doc, page);
            JTable table=gettable(pricelist,in);

            Object[] headercol={"Type","Asc","Ref","Commandes","Prix unitaire","Prix total"};
            Object[][] content=getTableData(table);
            Object[][] global=(Object[][]) concatenate (headercol,content);
            //drawTable(page, contentStream, 700, 75, headercol); 
            drawTable(page, contentStream, 700, 75, content); 
            contentStream.close();
            doc.save("bill.pdf" );
    }
    catch (IOException ex) {
        ex.printStackTrace();
    }

}   

public <T> T[] concatenate (T[] a, T[][] b) {
    int aLen = a.length;
    int bLen = b.length;

    @SuppressWarnings("unchecked")
    T[] c = (T[]) Array.newInstance(a.getClass().getComponentType(), aLen+bLen);
    System.arraycopy(a, 0, c, 0, aLen);
    System.arraycopy(b, 0, c, aLen, bLen);

    return c;
}
Community
  • 1
  • 1
m_h
  • 199
  • 1
  • 4
  • 14

2 Answers2

3
public <T> T[] concatenate (T[] a, T[][] b)

You cannot concatenate two array of different types. a is an array of Ts, b is an array of T[]s, i.e. it is an array of arrays of Ts.

Haris Osmanagić
  • 1,249
  • 12
  • 28
  • Thanks. That is true. However, the two arrays I am trying to concatenate have the same number of columns. Declaring Object[][] headercol throws Type mismatch: cannot convert String to Object[] – m_h Feb 22 '17 at 10:08
1

It seems like you want to concatenate the T[] a header and the T[][] b content, but your concatenate method returns a T[]. You have to return a T[][] instead, i.e. create an array of a.getClass() instead of a.getClass().getComponentType(). Also, in that new T[][] c, the T[] a will only take a single position, so the total length is just b.length + 1. Try this:

public <T> T[][] concatenate (T[] a, T[][] b) {
    T[][] c = (T[][]) Array.newInstance(a.getClass(), b.length + 1);
    c[0] = a;
    System.arraycopy(b, 0, c, 1, b.length);
    return c;
}

Since the above can only concatenate a 1D array to a 2D array, but not the other way around (as you'd need for adding a 'totals' line below the table, a more general approach would be to write a generic "join 2 arrays with same dimensions" method, and another method to wrap an element into an array.

public <T> T[] wrap(T x) {
    T[] a = (T[]) Array.newInstance(x.getClass(), 1);
    a[0] = x;
    return a;
}

public <T> T[] concatenate (T[] a, T[] b) {
    T[] c = (T[]) Array.newInstance(a.getClass().getComponentType(), a.length + b.length);
    System.arraycopy(a, 0, c, 0, a.length);
    System.arraycopy(b, 0, c, a.length, b.length);
    return c;
}

Example:

String[] headercol = {"Type","Asc","Ref","Commandes","Prix unitaire","Prix total"};
String[][] content = {{"A","B","C","D","E","F","G","H"}, {"1","2","3","4","5","6","7","8"}};
String[] footer = {"a","b","c","d","e","f","g","h"};

String[][] global = (String[][]) concatenate (wrap(headercol),content);
global = (String[][]) concatenate (global, wrap(footer));

for (String[] row : global) {
    System.out.println(Arrays.toString(row));
}

Output:

[Type, Asc, Ref, Commandes, Prix unitaire, Prix total]
[A, B, C, D, E, F, G, H]
[1, 2, 3, 4, 5, 6, 7, 8]
[a, b, c, d, e, f, g, h]
tobias_k
  • 81,265
  • 12
  • 120
  • 179
  • However, when trying to add the last line to the table, the one with the total price, I get an ArrayStoreException. It seems to me, I am doing exactly the same thing in the concatenate2 function as in the concatenate function. Here is the code I am using – m_h Feb 22 '17 at 15:26
  • @m_h The difference is that this function is adding the header as the _first_ element in the array, whereas the footer would need to be the last line. – tobias_k Feb 22 '17 at 15:29
  • I added the concatenate2 to your suggestion above since it is very similar to your concatenate function. Yet this throws the ArrayStoreException as I stated above. – m_h Feb 22 '17 at 15:35
  • @m_h See my update for a more general solution. BTW, the exception you got was because if `a` is the 2D array you have to use `a.getClass().getComponentType()` (or `b.getClass()`) – tobias_k Feb 22 '17 at 15:47