2929import java .io .Reader ;
3030import java .io .Serializable ;
3131import java .io .StringWriter ;
32+ import java .util .Arrays ;
3233
3334/**
3435 * The format specification of a CSV file.
3536 *
3637 * This class is immutable.
37- *
38+ *
3839 * @version $Id$
3940 */
4041public class CSVFormat implements Serializable {
@@ -125,8 +126,8 @@ public class CSVFormat implements Serializable {
125126
126127 /**
127128 * Creates a new CSV format builds.
128- *
129- * @param delimiter
129+ *
130+ * @param delimiter
130131 * the char used for value separation, must not be a line break character
131132 * @throws IllegalArgumentException if the delimiter is a line break character
132133 */
@@ -137,7 +138,7 @@ public static CSVFormatBuilder newBuilder(final char delimiter) {
137138 public static CSVFormatBuilder newBuilder (final CSVFormat format ) {
138139 return new CSVFormatBuilder (format );
139140 }
140-
141+
141142 /**
142143 * Standard comma separated format, as for {@link #RFC4180} but allowing blank lines.
143144 * <ul>
@@ -158,7 +159,7 @@ public static CSVFormatBuilder newBuilder() {
158159 * the char used for value separation, must not be a line break character
159160 * @param quoteChar
160161 * the char used as value encapsulation marker
161- * @param quotePolicy
162+ * @param quotePolicy
162163 * the quote policy
163164 * @param commentStart
164165 * the char used for comment identification
@@ -174,10 +175,12 @@ public static CSVFormatBuilder newBuilder() {
174175 * the header
175176 * @throws IllegalArgumentException if the delimiter is a line break character
176177 */
177- private CSVFormat (final char delimiter , final Character quoteChar , final Quote quotePolicy , final Character commentStart , final Character escape , final
178- boolean ignoreSurroundingSpaces , final boolean ignoreEmptyLines , final String lineSeparator ,
179- final String [] header ) {
180- if (isLineBreak (delimiter )) {
178+ private CSVFormat (final char delimiter , final Character quoteChar , final Quote quotePolicy , final Character commentStart , final Character escape , final
179+ boolean ignoreSurroundingSpaces , final boolean ignoreEmptyLines , final String lineSeparator ,
180+ final String [] header )
181+ {
182+ if (isLineBreak (delimiter ))
183+ {
181184 throw new IllegalArgumentException ("The delimiter cannot be a line break" );
182185 }
183186 this .delimiter = delimiter ;
@@ -188,7 +191,7 @@ private CSVFormat(final char delimiter, final Character quoteChar, final Quote q
188191 this .ignoreSurroundingSpaces = ignoreSurroundingSpaces ;
189192 this .ignoreEmptyLines = ignoreEmptyLines ;
190193 this .recordSeparator = lineSeparator ;
191- this .header = header ;
194+ this .header = header == null ? null : header . clone () ;
192195 }
193196
194197 /**
@@ -373,7 +376,109 @@ public String toString() {
373376 public Quote getQuotePolicy () {
374377 return quotePolicy ;
375378 }
376-
379+
380+ @ Override
381+ public int hashCode ()
382+ {
383+ final int prime = 31 ;
384+ int result = 1 ;
385+
386+ result = prime * result + delimiter ;
387+ result = prime * result + ((quotePolicy == null ) ? 0 : quotePolicy .hashCode ());
388+ result = prime * result + ((quoteChar == null ) ? 0 : quoteChar .hashCode ());
389+ result = prime * result + ((commentStart == null ) ? 0 : commentStart .hashCode ());
390+ result = prime * result + ((escape == null ) ? 0 : escape .hashCode ());
391+ result = prime * result + (ignoreSurroundingSpaces ? 1231 : 1237 );
392+ result = prime * result + (ignoreEmptyLines ? 1231 : 1237 );
393+ result = prime * result + ((recordSeparator == null ) ? 0 : recordSeparator .hashCode ());
394+ result = prime * result + Arrays .hashCode (header );
395+ return result ;
396+ }
397+
398+ @ Override
399+ public boolean equals (Object obj )
400+ {
401+ if (this == obj )
402+ {
403+ return true ;
404+ }
405+ if (obj == null )
406+ {
407+ return false ;
408+ }
409+ if (getClass () != obj .getClass ())
410+ {
411+ return false ;
412+ }
413+
414+ CSVFormat other = (CSVFormat ) obj ;
415+ if (delimiter != other .delimiter )
416+ {
417+ return false ;
418+ }
419+ if (quotePolicy != other .quotePolicy )
420+ {
421+ return false ;
422+ }
423+ if (quoteChar == null )
424+ {
425+ if (other .quoteChar != null )
426+ {
427+ return false ;
428+ }
429+ }
430+ else if (!quoteChar .equals (other .quoteChar ))
431+ {
432+ return false ;
433+ }
434+ if (commentStart == null )
435+ {
436+ if (other .commentStart != null )
437+ {
438+ return false ;
439+ }
440+ }
441+ else if (!commentStart .equals (other .commentStart ))
442+ {
443+ return false ;
444+ }
445+ if (escape == null )
446+ {
447+ if (other .escape != null )
448+ {
449+ return false ;
450+ }
451+ }
452+ else if (!escape .equals (other .escape ))
453+ {
454+ return false ;
455+ }
456+ if (!Arrays .equals (header , other .header ))
457+ {
458+ return false ;
459+ }
460+ if (ignoreSurroundingSpaces != other .ignoreSurroundingSpaces )
461+ {
462+ return false ;
463+ }
464+ if (ignoreEmptyLines != other .ignoreEmptyLines )
465+ {
466+ return false ;
467+ }
468+ if (recordSeparator == null )
469+ {
470+ if (other .recordSeparator != null )
471+ {
472+ return false ;
473+ }
474+ }
475+ else if (!recordSeparator .equals (other .recordSeparator ))
476+ {
477+ return false ;
478+ }
479+ return true ;
480+ }
481+
377482 public static class CSVFormatBuilder {
378483
379484 private char delimiter ;
@@ -393,7 +498,7 @@ public static class CSVFormatBuilder {
393498 * the char used for value separation, must not be a line break character
394499 * @param quoteChar
395500 * the char used as value encapsulation marker
396- * @param quotePolicy
501+ * @param quotePolicy
397502 * the quote policy
398503 * @param commentStart
399504 * the char used for comment identification
@@ -410,8 +515,8 @@ public static class CSVFormatBuilder {
410515 * @throws IllegalArgumentException if the delimiter is a line break character
411516 */
412517 // package protected for use by test code
413- CSVFormatBuilder (final char delimiter , final Character quoteChar , final Quote quotePolicy , final Character commentStart , final Character escape , final
414- boolean ignoreSurroundingSpaces , final boolean ignoreEmptyLines , final String lineSeparator ,
518+ CSVFormatBuilder (final char delimiter , final Character quoteChar , final Quote quotePolicy , final Character commentStart , final Character escape , final
519+ boolean ignoreSurroundingSpaces , final boolean ignoreEmptyLines , final String lineSeparator ,
415520 final String [] header ) {
416521 if (isLineBreak (delimiter )) {
417522 throw new IllegalArgumentException ("The delimiter cannot be a line break" );
@@ -426,11 +531,11 @@ public static class CSVFormatBuilder {
426531 this .recordSeparator = lineSeparator ;
427532 this .header = header ;
428533 }
429-
534+
430535 /**
431- *
536+ *
432537 * Creates a CSVFormatBuilder, using the values of the given CSVFormat.
433- *
538+ *
434539 * @param format
435540 * The format to use values from
436541 */
@@ -443,8 +548,8 @@ private CSVFormatBuilder(CSVFormat format) {
443548
444549 /**
445550 * Creates a basic CSVFormatBuilder.
446- *
447- * @param delimiter
551+ *
552+ * @param delimiter
448553 * the char used for value separation, must not be a line break character
449554 * @throws IllegalArgumentException if the delimiter is a line break character
450555 */
@@ -457,35 +562,35 @@ public CSVFormat build() {
457562 return new CSVFormat (delimiter , quoteChar , quotePolicy , commentStart , escape ,
458563 ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , header );
459564 }
460-
565+
461566 /**
462567 * Verifies the consistency of the parameters and throws an IllegalStateException if necessary.
463- *
568+ *
464569 * @throws IllegalStateException
465570 */
466571 private void validate () throws IllegalStateException {
467572 if (quoteChar != null && delimiter == quoteChar .charValue ()) {
468573 throw new IllegalStateException ("The quoteChar character and the delimiter cannot be the same ('" + quoteChar + "')" );
469574 }
470-
575+
471576 if (escape != null && delimiter == escape .charValue ()) {
472577 throw new IllegalStateException ("The escape character and the delimiter cannot be the same ('" + escape + "')" );
473578 }
474-
579+
475580 if (commentStart != null && delimiter == commentStart .charValue ()) {
476- throw new IllegalStateException ("The comment start character and the delimiter cannot be the same ('" + commentStart +
581+ throw new IllegalStateException ("The comment start character and the delimiter cannot be the same ('" + commentStart +
477582 "')" );
478583 }
479-
584+
480585 if (quoteChar != null && quoteChar .equals (commentStart )) {
481- throw new IllegalStateException ("The comment start character and the quoteChar cannot be the same ('" + commentStart +
586+ throw new IllegalStateException ("The comment start character and the quoteChar cannot be the same ('" + commentStart +
482587 "')" );
483588 }
484-
589+
485590 if (escape != null && escape .equals (commentStart )) {
486591 throw new IllegalStateException ("The comment start and the escape character cannot be the same ('" + commentStart + "')" );
487592 }
488-
593+
489594 if (escape == null && quotePolicy == Quote .NONE ) {
490595 throw new IllegalStateException ("No quotes mode set but no escape character is set" );
491596 }
@@ -504,7 +609,7 @@ public CSVFormatBuilder withDelimiter(final char delimiter) {
504609 if (isLineBreak (delimiter )) {
505610 throw new IllegalArgumentException ("The delimiter cannot be a line break" );
506611 }
507- this .delimiter = delimiter ;
612+ this .delimiter = delimiter ;
508613 return this ;
509614 }
510615
@@ -625,7 +730,7 @@ public CSVFormatBuilder withHeader(final String... header) {
625730 this .header = header ;
626731 return this ;
627732 }
628-
733+
629734 /**
630735 * Sets the trimming behavior of the format.
631736 *
0 commit comments