Skip to content

Commit e2c2fd4

Browse files
committed
CSVRecord.toList() does not give write access to the new List
1 parent 532e08c commit e2c2fd4

3 files changed

Lines changed: 46 additions & 7 deletions

File tree

src/changes/changes.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
<action issue="CSV-269" type="fix" dev="ggregory" due-to="Auke te Winkel, Gary Gregory">CSVRecord.get(Enum) should use Enum.name() instead of Enum.toString().</action>
4747
<action type="fix" dev="ggregory" due-to="Gary Gregory">Allow org.apache.commons.csv.IOUtils.copy(Reader, Appendable, CharBuffer) to compile on Java 11 and run on Java 8.</action>
4848
<action type="fix" dev="ggregory" due-to="Gary Gregory">Bump commons-parent from 52 to 53.</action>
49+
<action issue="CSV-300" type="fix" dev="ggregory" due-to="Markus Spann, Gary Gregory">CSVRecord.get(Enum) should use Enum.name() instead of Enum.toString().</action>
4950
<!-- ADD -->
5051
<action issue="CSV-291" type="add" dev="ggregory" due-to="Gary Gregory">Make CSVRecord#values() public.</action>
5152
<action issue="CSV-264" type="add" dev="ggregory" due-to="Sagar Tiwari, Seth Falco, Alex Herbert, Gary Gregory">Add DuplicateHeaderMode for flexibility with header strictness. #114.</action>

src/main/java/org/apache/commons/csv/CSVRecord.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.apache.commons.csv;
1919

2020
import java.io.Serializable;
21+
import java.util.ArrayList;
2122
import java.util.Arrays;
2223
import java.util.Iterator;
2324
import java.util.LinkedHashMap;
@@ -298,17 +299,26 @@ public Stream<String> stream() {
298299
}
299300

300301
/**
301-
* Converts the values to a List.
302+
* Converts the values to a new List.
303+
* <p>
304+
* Editing the list does not update this instance.
305+
* </p>
302306
*
303307
* @return a new List
304308
* @since 1.9.0
305309
*/
306310
public List<String> toList() {
307-
return Arrays.asList(values);
311+
// Only allocate a single list of known size
312+
final ArrayList<String> list = new ArrayList<>(values.length);
313+
Stream.of(values).forEach(list::add);
314+
return list;
308315
}
309316

310317
/**
311318
* Copies this record into a new Map of header name to record value.
319+
* <p>
320+
* Editing the map does not update this instance.
321+
* </p>
312322
*
313323
* @return A new Map. The map is empty if the record has no headers.
314324
*/

src/test/java/org/apache/commons/csv/CSVRecordTest.java

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717
package org.apache.commons.csv;
1818

19+
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
1920
import static org.junit.jupiter.api.Assertions.assertEquals;
2021
import static org.junit.jupiter.api.Assertions.assertFalse;
2122
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -30,6 +31,7 @@
3031
import java.io.ObjectOutputStream;
3132
import java.io.StringReader;
3233
import java.util.ArrayList;
34+
import java.util.List;
3335
import java.util.Map;
3436
import java.util.TreeMap;
3537
import java.util.concurrent.ConcurrentHashMap;
@@ -47,9 +49,7 @@ private enum EnumFixture {
4749

4850
/** This enum overrides toString() but it's the names that matter. */
4951
public enum EnumHeader {
50-
FIRST("first"),
51-
SECOND("second"),
52-
THIRD("third");
52+
FIRST("first"), SECOND("second"), THIRD("third");
5353

5454
private final String number;
5555

@@ -69,7 +69,7 @@ public String toString() {
6969

7070
@BeforeEach
7171
public void setUp() throws Exception {
72-
values = new String[] {"A", "B", "C"};
72+
values = new String[] { "A", "B", "C" };
7373
final String rowData = StringUtils.join(values, ',');
7474
try (final CSVParser parser = CSVFormat.DEFAULT.parse(new StringReader(rowData))) {
7575
record = parser.iterator().next();
@@ -273,14 +273,42 @@ public void testStream() {
273273
}
274274

275275
@Test
276-
public void testToList() {
276+
public void testToListAdd() {
277+
String[] expected = values.clone();
278+
final List<String> list = record.toList();
279+
list.add("Last");
280+
assertEquals("Last", list.get(list.size() - 1));
281+
assertEquals(list.size(), values.length + 1);
282+
assertArrayEquals(expected, values);
283+
}
284+
285+
@Test
286+
public void testToListFor() {
277287
int i = 0;
278288
for (final String value : record.toList()) {
279289
assertEquals(values[i], value);
280290
i++;
281291
}
282292
}
283293

294+
@Test
295+
public void testToListForEach() {
296+
AtomicInteger i = new AtomicInteger();
297+
record.toList().forEach(e -> {
298+
assertEquals(values[i.getAndIncrement()], e);
299+
});
300+
}
301+
302+
@Test
303+
public void testToListSet() {
304+
String[] expected = values.clone();
305+
final List<String> list = record.toList();
306+
list.set(list.size() - 1, "Last");
307+
assertEquals("Last", list.get(list.size() - 1));
308+
assertEquals(list.size(), values.length);
309+
assertArrayEquals(expected, values);
310+
}
311+
284312
@Test
285313
public void testToMap() {
286314
final Map<String, String> map = this.recordWithHeader.toMap();

0 commit comments

Comments
 (0)