From e2c2fd40a5a93984f10b4ad2c6115aeb58abcfd9 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 10 Aug 2022 05:51:53 -0400 Subject: [PATCH] CSVRecord.toList() does not give write access to the new List --- src/changes/changes.xml | 1 + .../org/apache/commons/csv/CSVRecord.java | 14 ++++++- .../org/apache/commons/csv/CSVRecordTest.java | 38 ++++++++++++++++--- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 96b3d8f8..88958978 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -46,6 +46,7 @@ CSVRecord.get(Enum) should use Enum.name() instead of Enum.toString(). Allow org.apache.commons.csv.IOUtils.copy(Reader, Appendable, CharBuffer) to compile on Java 11 and run on Java 8. Bump commons-parent from 52 to 53. + CSVRecord.get(Enum) should use Enum.name() instead of Enum.toString(). Make CSVRecord#values() public. Add DuplicateHeaderMode for flexibility with header strictness. #114. diff --git a/src/main/java/org/apache/commons/csv/CSVRecord.java b/src/main/java/org/apache/commons/csv/CSVRecord.java index b4925d74..942a73c0 100644 --- a/src/main/java/org/apache/commons/csv/CSVRecord.java +++ b/src/main/java/org/apache/commons/csv/CSVRecord.java @@ -18,6 +18,7 @@ package org.apache.commons.csv; import java.io.Serializable; +import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.LinkedHashMap; @@ -298,17 +299,26 @@ public final class CSVRecord implements Serializable, Iterable { } /** - * Converts the values to a List. + * Converts the values to a new List. + *

+ * Editing the list does not update this instance. + *

* * @return a new List * @since 1.9.0 */ public List toList() { - return Arrays.asList(values); + // Only allocate a single list of known size + final ArrayList list = new ArrayList<>(values.length); + Stream.of(values).forEach(list::add); + return list; } /** * Copies this record into a new Map of header name to record value. + *

+ * Editing the map does not update this instance. + *

* * @return A new Map. The map is empty if the record has no headers. */ diff --git a/src/test/java/org/apache/commons/csv/CSVRecordTest.java b/src/test/java/org/apache/commons/csv/CSVRecordTest.java index 042677f1..9cb7f31e 100644 --- a/src/test/java/org/apache/commons/csv/CSVRecordTest.java +++ b/src/test/java/org/apache/commons/csv/CSVRecordTest.java @@ -16,6 +16,7 @@ */ package org.apache.commons.csv; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -30,6 +31,7 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.StringReader; import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; @@ -47,9 +49,7 @@ public class CSVRecordTest { /** This enum overrides toString() but it's the names that matter. */ public enum EnumHeader { - FIRST("first"), - SECOND("second"), - THIRD("third"); + FIRST("first"), SECOND("second"), THIRD("third"); private final String number; @@ -69,7 +69,7 @@ public class CSVRecordTest { @BeforeEach public void setUp() throws Exception { - values = new String[] {"A", "B", "C"}; + values = new String[] { "A", "B", "C" }; final String rowData = StringUtils.join(values, ','); try (final CSVParser parser = CSVFormat.DEFAULT.parse(new StringReader(rowData))) { record = parser.iterator().next(); @@ -273,7 +273,17 @@ public class CSVRecordTest { } @Test - public void testToList() { + public void testToListAdd() { + String[] expected = values.clone(); + final List list = record.toList(); + list.add("Last"); + assertEquals("Last", list.get(list.size() - 1)); + assertEquals(list.size(), values.length + 1); + assertArrayEquals(expected, values); + } + + @Test + public void testToListFor() { int i = 0; for (final String value : record.toList()) { assertEquals(values[i], value); @@ -281,6 +291,24 @@ public class CSVRecordTest { } } + @Test + public void testToListForEach() { + AtomicInteger i = new AtomicInteger(); + record.toList().forEach(e -> { + assertEquals(values[i.getAndIncrement()], e); + }); + } + + @Test + public void testToListSet() { + String[] expected = values.clone(); + final List list = record.toList(); + list.set(list.size() - 1, "Last"); + assertEquals("Last", list.get(list.size() - 1)); + assertEquals(list.size(), values.length); + assertArrayEquals(expected, values); + } + @Test public void testToMap() { final Map map = this.recordWithHeader.toMap();