anarche
anarche

Reputation: 536

Update element of LinkedHashSet which is a collection

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

Answers (1)

user1738539
user1738539

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

Related Questions