Reputation: 536
I have a nested collection structure representing Schema, Table, Column
public class SSchema{
private String schemaName;
private LinkedHashSet<STable> tableSet;
}
public class STable {
private String tableFullName;
private String tableDisplayName;
private LinkedHashSet<SColumn> columnSet;
}
public class SColumn {
private String columnFullName;
private String columnDisplayName;
private String columnType;
}
I retrieve the list of columns from an API and populate a LinkedHashSet of columns, I then get the Tables these columns belong to and am trying to update the LinkedHashSet of Columns inside each Table. Unfortunately, there is no API to get the columns for a table in this API
LinkedHashSet<SColumn> sColumnSet = getSColumnsFromAPI();
LinkedHashSet<STable> sTableSet = getSTablesForColumns(sColumnSet);
In the function getSTablesForColumns,
private LinkedHashSet<STable> getSTablesForColumns(LinkedHashSet<SColumn> sColumnSet) throws IOException,JsonParseException {
sTableSet = new LinkedHashSet<STable>();
sColumnSet.forEach(sColumn -> {
String[] tablesList = getTablesFromApi(sColumn) //get the tables this column is in
foreach(String tableName:tablesList){
STable table = STable.builder()
.tableFullName(tableName)
.build();
//This is where the problem is - need a way to get the existing table
if(sTableSet.contains(table){
// get existing table from sTableSet - how do I do this?
existingTable.getColumnSet().add(stiboColumn);
}
else { //new table, not in collection
LinkedHashSet<SColumn> columnSet = new LinkedHashSet<SColumn>();
columnSet.add(sColumn);
table.setColumnSet(columnSet);
sTableSet.add(table);
};
}
});
return sTableSet;
}
The question/difficulty I am having is: How do I efficiently find the existing sTable in the LinkedHashSet and update the LinkedHashSet inside this sTable with the additional sColumn?
Edit: I came up with the following fix before the much better solution below:
My earlier solution was to check if the table existed in the collection (I had moved the sTableSet to a class variable):
boolean existingTable=false;
for(STable sTable : sTableSet){
String collectionSTableName = sTable.getTableFullName();
if (collectionSTableName.equals(table)){
existingTable=true;
sTable.getColumnSet().add(sColumn);
break;
}
}
if(existingTable==false) { //new table, not in collection
LinkedHashSet<SColumn> columnSet = new LinkedHashSet<SColumn>();
columnSet.add(sColumn);
table.setColumnSet(columnSet);
sTableSet.add(table);
};
Upvotes: 0
Views: 111
Reputation: 941
Your first line of getSTablesForColumns
you are reinitializing the global field sTableSet
. If you ever call this method again, you will be losing what was already stored.
However, aside from that you, the data structure you might be looking for is a HashMap
. (I've also changed the return type to void to avoid that first problem)
Class Test {
private Map<String, STable> sTableMap = new HashMap<>();
public Test() {
LinkedHashSet<SColumn> sColumnSet = getSColumnsFromAPI();
updateSTablesForColumns(sColumnSet); // sTableMap will be populated after this call
}
private void updateSTablesForColumns(LinkedHashSet<SColumn> sColumnSet) throws IOException,JsonParseException {
sColumnSet.forEach(sColumn -> {
String[] tablesList = getTablesFromApi(sColumn) //get the tables this column is in
for (String tableName : tablesList){
STable table = STable.builder()
.tableFullName(tableName)
.build();
STable existingTable = sTableMap.get(table.getTableFullName());
if(existingTable != null){
existingTable.getColumnSet().add(stiboColumn);
} else { //new table, not in collection
LinkedHashSet<SColumn> columnSet = new LinkedHashSet<SColumn>();
columnSet.add(sColumn);
table.setColumnSet(columnSet);
sTableMap.put(table.getTableFullName(), table);
}
}
});
}
}
Be aware about side effects and modifying your parameters inside functions. In your method here you are changing sColumnSet
by calling sColumnSet.add()
. Which means your paramter after the method call is now changed. Also you shouldn't add to a collection while iterating over it. You may even get an exception here columnSet.add(sColumn);
Upvotes: 1