I want to remove duplicate row in a 2d array . i tried the below code .but it is not working . please help me .
Input :
1,ram,mech
1,ram,mech
2,gopi,csc
2.gopi,civil
output should be :
1,ram,mech
2,gopi,csc
2.gopi,civil
Code :
package employee_dup;
import java.util.*;
public class Employee_dup {
public static void main(String[] args)
{
boolean Switch = true;
System.out.println("Name ID Dept ");
String[][] employee_t = {{"1","ram","Mech"},{"1","siva","Mech"},{"1","gopi","Mech"},{"4","jenkat","Mech"},{"5","linda","Mech"},{"1","velu","Mech"}};
int g = employee_t[0].length;
String[][] array2 = new String[10][g];
int rows = employee_t.length;
Arrays.sort(employee_t, new sort(0));
for(int i=0;i<employee_t.length;i++){
for(int j=0;j<employee_t[0].length;j++){
System.out.print(employee_t[i][j]+" ");
}
System.out.println();
}
List<String[]> l = new ArrayList<String[]>(Arrays.asList(employee_t));
for(int k = 0 ;k < employee_t.length-1;k++)
{
if(employee_t[k][0] == employee_t[k+1][0])
{
System.out.println("same value is present");
l.remove(1);
array2 = l.toArray(new String[][]{});
}
}
System.out.println("Name ID Dept ");
for(int i=0;i<array2.length;i++){
for(int j=0;j<array2[0].length;j++){
System.out.print(array2[i][j]+" ");
}
System.out.println();
}
}
}
class sort implements Comparator {
int j;
sort(int columnToSort) {
this.j = columnToSort;
}
//overriding compare method
public int compare(Object o1, Object o2) {
String[] row1 = (String[]) o1;
String[] row2 = (String[]) o2;
//compare the columns to sort
return row1[j].compareTo(row2[j]);
}
}
First I sorted the array based on column one ,then tried to remove duplicates by checking the first column elements and seconds column elements but it is not removing the required column but remove other columns.
You may give this solution a try:
public static void main(String[] args) {
String[][] employee_t = {
{"1","ram","Mech"},
{"1","ram","Mech"},
{"1","siva","Mech"},
{"1","siva","Mech"},
{"1","gopi","Mech"},
{"1","gopi","Mech"} };
System.out.println("ID Name Dept");
Arrays.stream(employee_t)
.map(Arrays::asList)
.distinct()
.forEach(row -> System.out.printf("%-3s%-7s%s\n", row.get(0), row.get(1), row.get(2)));
}
Output
ID Name Dept
1 ram Mech
1 siva Mech
1 gopi Mech
How it works: comparing arrays does rely on instance equality and not on comparing contained elements by equals. Hence converting each row of your 2D array into a List will enable you to compare lists, which takes equals of the elements contained into account.
The Java Stream API does provide a method distinct which relies on equals and will remove all duplicates for you.
Based on your code. Maybe it is not the BEST solution but it works.
public static void main(String[] args) {
System.out.println("Name ID Dept ");
// I added duplicated rows
String[][] inputArray = {
{ "1", "ram", "Mech" },
{ "1", "siva", "Mech" },
{ "1", "gopi", "Mech" },
{ "1", "gopi", "Mech" },
{ "4", "jenkat", "Mech" },
{ "5", "linda", "Mech" },
{ "1", "velu", "Mech" },
{ "1", "velu", "Mech" }
};
// I will add all rows in a Set as it doesn't store duplicate values
Set<String> solutionSet = new LinkedHashSet<String>();
// I get all rows, create a string and insert into Set
for (int i = 0 ; i < inputArray.length ; i++) {
String input = inputArray[i][0]+","+inputArray[i][1]+","+inputArray[i][2];
solutionSet.add(input);
}
// You know the final size of the output array
String[][] outputArray = new String[solutionSet.size()][3];
// I get the results without duplicated values and reconvert it to your format
int position = 0;
for(String solution : solutionSet) {
String[] solutionArray = solution.split(",");
outputArray[position][0] = solutionArray[0];
outputArray[position][1] = solutionArray[1];
outputArray[position][2] = solutionArray[2];
position++;
}
System.out.println("Name ID Dept ");
for (int i = 0; i < outputArray.length; i++) {
for (int j = 0; j < outputArray[0].length; j++) {
System.out.print(outputArray[i][j] + " ");
}
System.out.println();
}
}
I have posted what I think is a readable and easy to maintain solution.
I decided to use distinct from Stream which is part of Java 8
Returns a stream consisting of the distinct elements (according to Object.equals(Object)) of this stream. - https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#distinct--
Main.class
class Main {
public static void main(String[] args)
{
//Create a list of Employee objects
List<Employee> employeeList = new ArrayList<Employee>();
Employee e1 = new Employee(1, "ram", "mech");
Employee e2 = new Employee(1, "ram", "mech");
Employee e3 = new Employee(2, "gopi", "csc");
Employee e4 = new Employee(2, "gopi", "civil");
employeeList.add(e1);
employeeList.add(e2);
employeeList.add(e3);
employeeList.add(e4);
System.out.println("Before removing duplicates");
employeeList.stream().forEach(System.out::println);
//This is where all the magic happens.
employeeList = employeeList.stream().distinct().collect(Collectors.toList());
System.out.println("\nAfter removing duplicates");
employeeList.stream().forEach(System.out::println);
}
}
Output:
Before removing duplicates
Employee [valA=1, valB=ram, valC=mech]
Employee [valA=1, valB=ram, valC=mech]
Employee [valA=2, valB=gopi, valC=csc]
Employee [valA=2, valB=gopi, valC=civil]
After removing duplicates
Employee [valA=1, valB=ram, valC=mech]
Employee [valA=2, valB=gopi, valC=csc]
Employee [valA=2, valB=gopi, valC=civil]
Employee.class
//This is just a regular POJO class.
class Employee {
int valA;
String valB, valC;
public Employee(int valA, String valB, String valC){
this.valA = valA;
this.valB = valB;
this.valC = valC;
}
public Employee(Employee e) {
this.valA = e.valA;
this.valB = e.valB;
this.valC = e.valC;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + valA;
result = prime * result + ((valB == null) ? 0 : valB.hashCode());
result = prime * result + ((valC == null) ? 0 : valC.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if(obj instanceof Employee && ((Employee)obj).hashCode() == this.hashCode()){
return true;
}
return false;
}
#Override
public String toString() {
return "Employee [valA=" + valA + ", valB=" + valB + ", valC=" + valC + "]";
}
}
Pre Java - 8 solution. May not be the best way. But a quick solution which works..
String[][] records = {
{"1","ram","Mech"},
{"1","ram","Mech"},
{"1","gopi","csc"},
{"1","gopi","civil"} };
List<String[]> distinctRecordsList = new ArrayList<String[]>();
for(String[] record : records){
if(distinctRecordsList.size()>0){
boolean sameValue = false;
for(String[] distinctRecord : distinctRecordsList){
int distinctRecordFields = distinctRecord.length;
if(record.length==distinctRecordFields){
for(int k=0;k<distinctRecordFields;k++){
sameValue = record[k].equalsIgnoreCase(distinctRecord[k]);
if(!sameValue)
break;
}
}else
throw new Exception("Can't compare the records");
}
if(!sameValue)
distinctRecordsList.add(record);
}else if(distinctRecordsList.size()==0)
distinctRecordsList.add(record);
}
Object[] distRecObjects = distinctRecordsList.toArray();
String[][] distinctRecordsArray = new String[distRecObjects.length][];
int i=0;
for(Object distRecObject : distRecObjects){
distinctRecordsArray[i] = (String[]) distRecObject;
i++;
}
Contrary to some other answers I will try to explain what went wrong in your own code and how to fix it within your code (I agree very much with kkflf that an Employee class would be a huge benefit: it’s more object-oriented and it will help structure the code and give better overview of it).
The issues I see in your code are:
You are not removing the correct element when you detect a duplicate, but always the element at index 1 (the second element since indices count from 0). This isn’t trivial, though, because indices shift as you remove elements. The trick is to iterate backward so only indices that you are finished with shift when you remove an element.
You are using == to compare the first element of the subarrays you are comparing. If you wanted to compare just the first element, you should use equals() for comparison. However, I believe you want to compare the entire row so 2,gopi,csc and 2.gopi,civil are recognized as different and both preserved. Arrays.equals() can do the job.
You need to create array2 only after the loop. As your code stands, if no duplicates are detected, arrays2 is never created.
So your loop becomes:
for (int k = employee_t.length - 1; k >= 1; k--)
{
if (Arrays.equals(employee_t[k], employee_t[k - 1]))
{
System.out.println("same value is present");
l.remove(k);
}
}
array2 = l.toArray(new String[][]{});
This gives you the output you asked for.
Further tips:
Your comparator only compares one field in the inner arrays, which is not enough to guarantee that identical rows come right after each other in the sorted array. You should compare all elements, and also require that the inner arrays have the same length.
Use generics: class Sort extends Comparator<String[]>, and you won’t need the casts in compare()
According to Java naming conventions it should be class EmployeeDup, boolean doSwitch (since switch is a reserved word) and class Sort.
You are not using the variables Switch and rows; delete them.
I have wrote a solution for me. This may not be the best but it works.
public static String[][] removeDuplicate(String[][] matrix) {
String[][] newMatrix = new String[matrix.length][matrix[0].length];
int newMatrixRow = 1;
for (int i = 0; i < matrix[0].length; i++)
newMatrix[0][i] = matrix[0][i];
for (int j = 1; j < matrix.length; j++) {
List<Boolean> list = new ArrayList<>();
for (int i = 0; newMatrix[i][0] != null; i++) {
boolean same = true;
for (int col = 2; col < matrix[j].length; col++) {
if (!newMatrix[i][col].equals(matrix[j][col])) {
same = false;
break;
}
}
list.add(same);
}
if (!list.contains(true)) {
for (int i = 0; i < matrix[j].length; i++) {
newMatrix[newMatrixRow][i] = matrix[j][i];
}
newMatrixRow++;
}
}
int i;
for(i = 0; newMatrix[i][0] != null; i++);
String finalMatrix[][] = new String[i][newMatrix[0].length];
for (i = 0; i < finalMatrix.length; i++) {
for (int j = 0; j < finalMatrix[i].length; j++)
finalMatrix[i][j] = newMatrix[i][j];
}
return finalMatrix;
}
This method will return a matrix without any duplicate rows.
Related
I have a simple problem. I have an ArrayList (of type String) with 100'000 Names. I want to create another ArrayList (of type Integer) which also has 100'000 Elements and assignes each Element of the String ArrayList an ID-Number. Equal Names should have equal ID Numbers assigned. VERY BASIC EXAMPLE:
i have: (hans, max, hans, hans, frank)
i want: ( 1 , 2 , 1 , 1 , 3 )
I implemented a Solution which works, but is very slow (for my big dataset of 100'000 Names). I wonder someone can find a better/faster way of doing this. Thanks everyone for any tipps!
public static void main(String[] args) {
// initialize arraylists
ArrayList<String> Names = new ArrayList<String>();
ArrayList<Integer> Id = new ArrayList<Integer>();
// sample data // I want the integer Arraylist to have values:
Names.add("Hans"); // 1
Names.add("Max"); // 2
Names.add("Hans"); // 1
Names.add("Hans"); // 1
Names.add("Frank"); // 3
// my solution (works, but is slow and confusing)
int N = Names.size();
int ID_Count = 0;
for (int i=0; i<N; i++) {
boolean match_found = false;
String curr_Name = Names.get(i);
for (int check=0; check<i; check++) {
if (curr_Name.equals(Names.get(check))) {
Id.add(Id.get(check));
match_found = true;
break;
}
}
if (match_found==false) {
ID_Count++;
Id.add(ID_Count);
}
}
// show result
for (int i=0; i<N; i++) {
System.out.println(Id.get(i) + " " + Names.get(i));
}
}
This is a faster way of doing it:
public static void main(String[] args) {
// initialize arraylists
ArrayList<String> Names = new ArrayList<String>();
Map<String,Integer> map = new HashMap<>();
// sample data // I want the integer Arraylist to have values:
Names.add("Hans"); // 1
Names.add("Max"); // 2
Names.add("Hans"); // 1
Names.add("Hans"); // 1
Names.add("Frank"); // 3
int N = Names.size();
int id = 0;
for (int i = 0; i < N; i++) {
String name = Names.get(i);
if (map.get(name) == null) {
map.put(name,++id);
}
}
// show result
for (int i=0; i<N; i++) {
String name = Names.get(i);
System.out.println(map.get(name) + " " +name);
}
}
If I understand your question correctly, you ought to use a HashMap, as it will be a lot faster/easier than working with two arrays. I would do it like this:
Map<String,Integer> map = new HashMap<>();
This way you will be able to do map.put("name", int id), and it won't allow duplicate keys (key is the "name" in your case) so you will automatically have only one key/value pair for names that are the same.
My professor gave out a review question for our midterm this week that I'm confused on:
Write a method that is given a two-dimensional (ragged) array of
String objects and returns a two-dimensional (ragged) array of String
objects where all the null entries have been removed. For example,
if the original array has the data (NULL represents a null
reference):
{"John", null, "Mary", "George", null},{null, "Pete", "Rick"},{null, null, null}};
the result generated by your method will be a two-dimensional
array with three rows.
{"John", "Mary", "George"},{"Pete", "Rick"},{}}; // last row will be empty
The code I have is:
public static String[][] removeNull2D(String[][] ragged) {
int counter = 0;
int nullCounter = 0;
String[][] array; // isn't initialized
// doesn't work I tested in debugger, need a way to shorten each row by the amount of null values it has
for (int i = 0; i < ragged.length; i++) {
for (int j = 0; j < ragged[i].length; j++) {
if (ragged[i][j] == null) {
nullCounter++;
for (j = 0; j < ragged[i].length; j++) {
array = new String[ragged.length][ragged[i].length - nullCounter];
}
}
}
}
// based off 1D array approach
for (int i = 0; i < ragged.length; i++) {
for (int j = 0; j < ragged[i].length; j++) {
if (ragged[i][j] != null) {
array[i][counter++] = ragged[i][j];
}
}
}
return ragged;
}
I understand I need to count the amount of null values in each row and subtract that from the total length of each row for the String array "array" (bad name I know). I thought maybe if I made a method for a 1D array, it would help me understand the logic a little better:
public static String[] removeNull1D(String[] a) {
String[] array = new String[a.length - 1];
int counter = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] != null) {
array[counter++] = a[i];
}
}
a = array;
return array;
}
Still confused how the logic applies to the 2D ragged array method, any clarification would be appreciated! Also, I don't believe I can import anything (are not supposed to at least), and once again this is just a review question, so I'm not stressing about getting an answer, just trying to understand the logic behind it.
You could try it like this:
public static void main(String[] args) {
String[][] ragged = { { "John", null, "Mary", "George", null }, { null, "Pete", "Rick" }, { null, null, null } };
String[][] cleaned = new String[ragged.length][];
for (int i = 0; i < ragged.length; i++) {
cleaned[i] = clean(ragged[i]); // Apply clean method to each sub array.
}
System.out.println(Arrays.deepToString(cleaned));
}
private static String[] clean(String[] dirty) {
int nonNullCount = 0;
for (String string : dirty) {
if (string != null) {
nonNullCount++; // Count non-null Strings.
}
}
String[] clean = new String[nonNullCount]; // Create array for non-null Strings.
int cleanIndex = 0;
for (String string : dirty) {
if (string != null) {
clean[cleanIndex] = string; // Insert only non-null String at index.
cleanIndex++; // Only then update index.
}
}
return clean;
}
Seems a little bit inelegant to me, but at the moment I can't think of a way to prevent the double loop in clean(String[] dirty)
Nevertheless, it outputs [[John, Mary, George], [Pete, Rick], []] as desired.
Edit: Updated some commentary.
I would like to iterate through two dimensional ArrayList which includes String objects using iterator. I also would like to iterate in a way that let me choose whether I want to iterate horizontally(row) first or vertically(column) by using a boolean value. How can I implement this in java?
What I've tried so far.
public class IterateThis implements Iterator<String>{
ArrayList<ArrayList<String>> array;
public IterateThis(){
array = new ArrayList<ArrayList<String>>();
array.add(new ArrayList<String>());
array.add(new ArrayList<String>());
array.add(new ArrayList<String>());
array.get(0).add("1");
array.get(0).add("2");
array.get(0).add("2");
array.get(1).add("4");
array.get(1).add("5");
array.get(1).add("6");
}
Iterator<String> it = array.iterator(); //This gives me an error...why?
I don't know how I can implement the boolean value though.
Maybe you need to implement two versions, with a boolean that decides which loop to use:
public void iterate(boolean horizantalFirst){
if(horizontalFirst){
for(int i=0; i<array.size(); i++){ // first iterate through the "outer list"
for(int j=0; j<array.get(i).size(); j++){ // then iterate through all the "inner lists"
array.get(i).get(j)="1";
}
}
}else{
int j=0; // index to iterate through the "inner lists"
for(; j<array.get(j).size(); j++){ //dangerous, you need to be sure that there is a j-th element in array
for(int i=0; i<array.size(); i++){ // iterate here through the outer list, by always working on the j-th element
array.get(i).get(j)="1";
}
}
}
}
Why not try this:
import java.util.ArrayList;
public class Iteration
{
private ArrayList<ArrayList<String>> array;
public Iteration()
{
array = new ArrayList<>();
array.add(new ArrayList<String>());
array.get(0).add("000");
array.get(0).add("001");
array.get(0).add("010");
array.add(new ArrayList<String>());
array.get(1).add("100");
array.get(1).add("101");
array.get(1).add("110");
array.get(1).add("111");
iterateRowWise();
System.out.println("\n\n");
iterateColumnWise();
}
public void iterateRowWise()
{
// This uses iterator behind the scene.
for (ArrayList<String> row : array)
{
for (String element : row)
{
System.out.print(element + " ");
}
System.out.println();
}
}
public void iterateColumnWise()
{
int arraySize = array.size();
int maxColumns = getMaximumListSize();
for (int c = 0; c < maxColumns; c++)
{
for (int r = 0; r < arraySize; r++)
{
ArrayList<String> rowList = array.get(r);
if (c < rowList.size())
{
System.out.print(rowList.get(c) + " ");
}
}
System.out.println();
}
}
private int getMaximumListSize()
{
int maxListSize = 0;
for (ArrayList<String> rowList : array)
{
if (maxListSize < rowList.size())
maxListSize = rowList.size();
}
return maxListSize;
}
public static void main(String[] args)
{
new Iteration();
}
}
The iterateRowWise() method iterates using the iterator, but it does so behind the scene.
The iterateColumnWise() method doesn't use iterator, but its safe to use.
Row-wise iteration is simple as shown in the #Awfully Awesome answer.
Tried a columnwise iteration with assumption that List will always have m cross n elements where m=n
public static void IterateThis() {
ArrayList<ArrayList<String>> array = new ArrayList<ArrayList<String>>();
array.add(new ArrayList<String>());
array.add(new ArrayList<String>());
array.get(0).add("1");
array.get(0).add("2");
array.get(0).add("2");
array.get(1).add("4");
array.get(1).add("5");
array.get(1).add("6");
Iterator<ArrayList<String>> it = array.iterator();
int topLevelIteratorResetCounter = 0;
int noOfIteratorNextRequired = 1;
int size = array.size();
while (it.hasNext()) {
ArrayList<String> strList = it.next();
if (noOfIteratorNextRequired > strList.size())
break;
Iterator<String> itString = strList.iterator();
int numtimes = 0;
String str = null;
while (numtimes != noOfIteratorNextRequired) {
str = itString.next();
numtimes++;
}
System.out.println(str);
numtimes = 0;
topLevelIteratorResetCounter++;
if (topLevelIteratorResetCounter == size) { //as column count is equal to column size
it = array.iterator(); //reset the iterator
noOfIteratorNextRequired++;
topLevelIteratorResetCounter = 0;
}
}
}
The answer uses Iterator.
I want to sort my String[][] with respect to second column. I tried this
public static String[][] sorting_minn(String[][] list){
double[] temp = new double[list.length];
String[][] tempf = list;
if(list[1][1]!=null){
for(int i = 0; i<list.length; i++){
if(list[i][2]==null){
break;
} else {
temp[i]=Double.parseDouble(list[i][2]);
}
}
Arrays.sort(temp);
for(int f = 0; f<list.length-1;f++){
for(int m = 0; m<list.length;m++){
if(list[m][2]!=null && Double.parseDouble(list[m][2])==temp[f]){
for(int n = 0; n<4; n++){
tempf[list.length-f-1][n]=list[m][n];
}
m = list.length;
}
}
}
}
return tempf;
}
As an output I get this: . I need suggestion on how to improve this code.
try something like:
Arrays.sort(list, new Comparator<String[]>() {
#Override
public int compare(String[] o1, String[] o2) {
String left = o1[1]!=null ? o1[1] : "";
String right = o2[1]!=null ? o2[1] : "";
return left.compareTo(right);
}
});
this treats nulls as empty strings, and exploits the fact that strings are comparable, although lexicographic. if you want the reverse order just do this instead:
right.compareTo(left)
if you want integer ordering you could parse an Integer out of both sides (Integer.MIN for null) and compare 2 Integers
If my sample data is a CSV file that looks like this:
a,,,b,
36,28,90,5,24
what would be the best way to either have something like
myStringArray = [a, [36,28,90]], [b, [5,24]]
or
myStringArray1 = {a,b}; // this part i can do
myStringArray2 = {{36,28,90}, {5,24}};
I am using Processing, which is based on Java, but my question is more about the general functionality of Java, so excuse my code formatting, if it doesn't appear java correct.
here is my import class:
class dTable {
int rowCount;
int columnCount;
String[][] data;
String filename;
dTable(String _filename) {
filename = _filename;
}
void load() {
String[] rows = loadStrings(filename);
String[] columns = split(rows[0], ',');
rowCount = rows.length;
columnCount = columns.length;
//set the size of the matrix
data = new String[rows.length][columns.length];
// add column pieces into data matrix
for (int i = 0; i < rows.length; i++) {
String[] colEntries = split(rows[i], ',');
for (int j = 0; j < columns.length; j++) {
data[i][j] = colEntries[j];
}
}
}
}
and here is my unworking attempts at a parsing class:
class dParse {
String[] bMaj;
String[][] bMin;
dParse() {
}
void getList(int integer) {
ArrayList dMaj = new ArrayList();
ArrayList dMin = new ArrayList();
String[][] minimums;
String[] _rowNameMaj = table.data[0]; //get data first to match
String[] _rowName = table.data[integer]; // get data to fill
//get first variables
for (int i = 0; i<_rowName.length; i++) { //iterate over
ArrayList tempMin = new ArrayList();
if (trim(_rowNameMaj[i]).length() != 0) {
dMaj.add(_rowNameMaj[i]);
}
}
//place maj values from arraylist into an array
String[] _bMaj = (String[]) dMaj.toArray(new String[0]);
bMaj = _bMaj; //set value to global variable
//min values
ArrayList bigOne = new ArrayList();
int count = 0;
for (int i = 0; i<_rowName.length; i++) { //iterate over
ArrayList tempMin = new ArrayList();
if (trim(_rowNameMaj[i]).length() != 0) { //check if box is not empty & set count to 0
//tempMin = dMaj.get(i); // set inner list
//println("maj " + count + " " + _rowNameMaj[i]);
tempMin.add(_rowName[i]);
count++;
//println("min" + count + " " + tempMin);
}
else if (trim(_rowNameMaj[i]).length() == 0) { //if next box is empty, add to count
count++;
tempMin.add(_rowName[i]);
//println("min" + count + " ");
}
minimums = new String[_bMaj.length][];
/various unworking attempts below
//place min values from arraylist into an array
//String[] temp_bMin = (String[]) tempMin.toArray(new String[0]);
//fl[] = append((new String(temp_bMin)), fl);
for (int n = 0; n< bMaj.lenth; n++ ) {
count[level]mums[n] = (String[]) toArray(new String[0]);
// println(minimums[n]);
// }
tempMin.clear(); //clear temporaryList
}
}
String[] getMaj() {
return bMaj;
}
String[][] getMin() {
return bMin;
}
}
Any help is appreciated,
Many thanks,
Dimitar
Dimitar... Perhaps a library such as Commons CSV or the links to the other libraries on that page would prove useful? However, if you insist on rolling your own CSV parser, look into the java.util.StringTokenizer class.
Pseudo code:
class Item {
String name;
List<String> values;
}
String[] names = line1.split(",");
String[] data = line2.split(",");
List<Item> items = new ArrayList<Item>();
Item curItem = null;
for (int i=0; i<data.length, i++)
{
if (names[i].isEmpty())
{
if (curItem == null) throw "first name is empty";
}
else
{
curItem = new Item();
items.add(curItem);
}
curItem.values.add(data[i]);
}
This uses an Item class to hold each item and a List<Item> for the whole thing. Downgrading to use nested arrays is left as an exercise.
Important If you need real CSV parsing (quoted fields, etc) you should use a CSV library to do the initial split and then apply the logic above to the results.