/**
  * Mutant factory method that will construct a new instance in which columns are sorted based on
  * names given as argument. Columns not listed in argument will be sorted after those within list,
  * using existing ordering.
  *
  * <p>For example, schema that has columns:
  *
  * <pre>"a", "d", "c", "b"
  * </pre>
  *
  * ordered with <code>schema.sortedBy("a", "b");</code> would result instance that columns in
  * order:
  *
  * <pre>"a", "b", "d", "c"
  * </pre>
  *
  * @since 2.4
  */
 public CsvSchema sortedBy(String... columnNames) {
   LinkedHashMap<String, Column> map = new LinkedHashMap<String, Column>();
   for (String colName : columnNames) {
     Column col = _columnsByName.get(colName);
     if (col != null) {
       map.put(col.getName(), col);
     }
   }
   for (Column col : _columns) {
     map.put(col.getName(), col);
   }
   return new CsvSchema(this, map.values().toArray(new Column[map.size()]));
 }
 /**
  * Mutant factory method that will construct a new instance in which columns are sorted using
  * given {@link Comparator} over column names.
  *
  * @since 2.4
  */
 public CsvSchema sortedBy(Comparator<String> cmp) {
   TreeMap<String, Column> map = new TreeMap<String, Column>(cmp);
   for (Column col : _columns) {
     map.put(col.getName(), col);
   }
   return new CsvSchema(this, map.values().toArray(new Column[map.size()]));
 }
  /** @since 2.5 */
  public CsvSchema(
      Column[] columns,
      int features,
      char columnSeparator,
      int quoteChar,
      int escapeChar,
      char[] lineSeparator,
      int arrayElementSeparator,
      char[] nullValue) {
    if (columns == null) {
      columns = NO_COLUMNS;
    } else {
      columns = _link(columns);
    }
    _columns = columns;
    _features = features;
    _columnSeparator = columnSeparator;
    _arrayElementSeparator = arrayElementSeparator;
    _quoteChar = quoteChar;
    _escapeChar = escapeChar;
    _lineSeparator = lineSeparator;
    _nullValue = nullValue;

    // and then we may need to create a mapping
    if (_columns.length == 0) {
      _columnsByName = Collections.emptyMap();
    } else {
      _columnsByName = new HashMap<String, Column>(4 + _columns.length);
      for (Column c : _columns) {
        _columnsByName.put(c.getName(), c);
      }
    }
  }
 /** Method for getting description of column definitions in developer-readable form */
 public String getColumnDesc() {
   StringBuilder sb = new StringBuilder(100);
   for (Column col : _columns) {
     if (sb.length() == 0) {
       sb.append('[');
     } else {
       sb.append(',');
     }
     sb.append('"');
     sb.append(col.getName());
     sb.append('"');
   }
   sb.append(']');
   return sb.toString();
 }
  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder(150);
    sb.append("[CsvSchema: ").append("columns=[");
    boolean first = true;
    for (Column col : _columns) {
      if (first) {
        first = false;
      } else {
        sb.append(',');
      }
      sb.append('"');
      sb.append(col.getName());
      sb.append("\"/");
      sb.append(col.getType());
    }
    sb.append(']');
    sb.append(", header? ").append(usesHeader());
    sb.append(", skipFirst? ").append(skipsFirstDataRow());
    sb.append(", comments?? ").append(allowsComments());

    sb.append(']');
    return sb.toString();
  }