Repository: jtablesaw/tablesaw
Pull request #879 (2021-01-26 17:01:44)

Use existing charset when available for creating reader
Thanks for contributing.

- [X] Tick to sign-off your agreement to the [Developer Certificate of Origin (DCO) 1.1](https://developercertificate.org)



Patch:
diff --git a/core/src/main/java/tech/tablesaw/api/DoubleColumn.java b/core/src/main/java/tech/tablesaw/api/DoubleColumn.java
index a36f167d..69f38657 100644
--- a/core/src/main/java/tech/tablesaw/api/DoubleColumn.java
+++ b/core/src/main/java/tech/tablesaw/api/DoubleColumn.java
@@ -1,13 +1,7 @@
 package tech.tablesaw.api;
 
 import com.google.common.base.Preconditions;
-import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
-import it.unimi.dsi.fastutil.doubles.DoubleArrays;
-import it.unimi.dsi.fastutil.doubles.DoubleComparators;
-import it.unimi.dsi.fastutil.doubles.DoubleIterator;
-import it.unimi.dsi.fastutil.doubles.DoubleListIterator;
-import it.unimi.dsi.fastutil.doubles.DoubleOpenHashSet;
-import it.unimi.dsi.fastutil.doubles.DoubleSet;
+import it.unimi.dsi.fastutil.doubles.*;
 import java.math.BigDecimal;
 import java.nio.ByteBuffer;
 import java.util.Collection;
@@ -23,6 +17,7 @@ import tech.tablesaw.columns.numbers.FloatColumnType;
 import tech.tablesaw.columns.numbers.NumberColumnFormatter;
 import tech.tablesaw.columns.numbers.NumberFillers;
 import tech.tablesaw.columns.numbers.fillers.DoubleRangeIterable;
+import tech.tablesaw.selection.BitmapBackedSelection;
 import tech.tablesaw.selection.Selection;
 
 public class DoubleColumn extends NumberColumn<DoubleColumn, Double>
@@ -153,6 +148,24 @@ public class DoubleColumn extends NumberColumn<DoubleColumn, Double>
     return (DoubleColumn) super.where(selection);
   }
 
+  public Selection isNotIn(final double... doubles) {
+    final Selection results = new BitmapBackedSelection();
+    results.addRange(0, size());
+    results.andNot(isIn(doubles));
+    return results;
+  }
+
+  public Selection isIn(final double... doubles) {
+    final Selection results = new BitmapBackedSelection();
+    final DoubleRBTreeSet doubleSet = new DoubleRBTreeSet(doubles);
+    for (int i = 0; i < size(); i++) {
+      if (doubleSet.contains(getDouble(i))) {
+        results.add(i);
+      }
+    }
+    return results;
+  }
+
   @Override
   public DoubleColumn subset(int[] rows) {
     final DoubleColumn c = this.emptyCopy();
diff --git a/core/src/main/java/tech/tablesaw/api/FloatColumn.java b/core/src/main/java/tech/tablesaw/api/FloatColumn.java
index 7fddd36e..130359de 100644
--- a/core/src/main/java/tech/tablesaw/api/FloatColumn.java
+++ b/core/src/main/java/tech/tablesaw/api/FloatColumn.java
@@ -1,12 +1,7 @@
 package tech.tablesaw.api;
 
 import com.google.common.base.Preconditions;
-import it.unimi.dsi.fastutil.floats.FloatArrayList;
-import it.unimi.dsi.fastutil.floats.FloatArrays;
-import it.unimi.dsi.fastutil.floats.FloatComparators;
-import it.unimi.dsi.fastutil.floats.FloatListIterator;
-import it.unimi.dsi.fastutil.floats.FloatOpenHashSet;
-import it.unimi.dsi.fastutil.floats.FloatSet;
+import it.unimi.dsi.fastutil.floats.*;
 import java.nio.ByteBuffer;
 import java.util.Iterator;
 import java.util.stream.Stream;
@@ -14,6 +9,8 @@ import tech.tablesaw.columns.AbstractColumnParser;
 import tech.tablesaw.columns.Column;
 import tech.tablesaw.columns.numbers.FloatColumnType;
 import tech.tablesaw.columns.numbers.NumberColumnFormatter;
+import tech.tablesaw.selection.BitmapBackedSelection;
+import tech.tablesaw.selection.Selection;
 
 public class FloatColumn extends NumberColumn<FloatColumn, Float> {
 
@@ -93,6 +90,24 @@ public class FloatColumn extends NumberColumn<FloatColumn, Float> {
     return c;
   }
 
+  public Selection isNotIn(final float... numbers) {
+    final Selection results = new BitmapBackedSelection();
+    results.addRange(0, size());
+    results.andNot(isIn(numbers));
+    return results;
+  }
+
+  public Selection isIn(final float... numbers) {
+    final Selection results = new BitmapBackedSelection();
+    final FloatRBTreeSet doubleSet = new FloatRBTreeSet(numbers);
+    for (int i = 0; i < size(); i++) {
+      if (doubleSet.contains(getFloat(i))) {
+        results.add(i);
+      }
+    }
+    return results;
+  }
+
   @Override
   public int size() {
     return data.size();
diff --git a/core/src/main/java/tech/tablesaw/api/IntColumn.java b/core/src/main/java/tech/tablesaw/api/IntColumn.java
index e45faabc..01abef35 100644
--- a/core/src/main/java/tech/tablesaw/api/IntColumn.java
+++ b/core/src/main/java/tech/tablesaw/api/IntColumn.java
@@ -1,13 +1,7 @@
 package tech.tablesaw.api;
 
 import com.google.common.base.Preconditions;
-import it.unimi.dsi.fastutil.ints.IntArrayList;
-import it.unimi.dsi.fastutil.ints.IntArrays;
-import it.unimi.dsi.fastutil.ints.IntComparators;
-import it.unimi.dsi.fastutil.ints.IntIterator;
-import it.unimi.dsi.fastutil.ints.IntListIterator;
-import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
-import it.unimi.dsi.fastutil.ints.IntSet;
+import it.unimi.dsi.fastutil.ints.*;
 import java.nio.ByteBuffer;
 import java.util.Iterator;
 import java.util.stream.IntStream;
@@ -16,6 +10,8 @@ import tech.tablesaw.columns.Column;
 import tech.tablesaw.columns.numbers.DoubleColumnType;
 import tech.tablesaw.columns.numbers.IntColumnType;
 import tech.tablesaw.columns.numbers.NumberColumnFormatter;
+import tech.tablesaw.selection.BitmapBackedSelection;
+import tech.tablesaw.selection.Selection;
 
 public class IntColumn extends NumberColumn<IntColumn, Integer>
     implements CategoricalColumn<Integer> {
@@ -432,6 +428,24 @@ public class IntColumn extends NumberColumn<IntColumn, Integer>
     return result;
   }
 
+  public Selection isIn(final int... numbers) {
+    final Selection results = new BitmapBackedSelection();
+    final IntRBTreeSet intSet = new IntRBTreeSet(numbers);
+    for (int i = 0; i < size(); i++) {
+      if (intSet.contains(getInt(i))) {
+        results.add(i);
+      }
+    }
+    return results;
+  }
+
+  public Selection isNotIn(final int... numbers) {
+    final Selection results = new BitmapBackedSelection();
+    results.addRange(0, size());
+    results.andNot(isIn(numbers));
+    return results;
+  }
+
   /**
    * Returns a new DoubleColumn containing a value for each value in this column, truncating if
    * necessary.
diff --git a/core/src/main/java/tech/tablesaw/api/LongColumn.java b/core/src/main/java/tech/tablesaw/api/LongColumn.java
index 81a3f7b3..e1011ab4 100644
--- a/core/src/main/java/tech/tablesaw/api/LongColumn.java
+++ b/core/src/main/java/tech/tablesaw/api/LongColumn.java
@@ -1,13 +1,7 @@
 package tech.tablesaw.api;
 
 import com.google.common.base.Preconditions;
-import it.unimi.dsi.fastutil.longs.LongArrayList;
-import it.unimi.dsi.fastutil.longs.LongArrays;
-import it.unimi.dsi.fastutil.longs.LongComparators;
-import it.unimi.dsi.fastutil.longs.LongIterator;
-import it.unimi.dsi.fastutil.longs.LongListIterator;
-import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
-import it.unimi.dsi.fastutil.longs.LongSet;
+import it.unimi.dsi.fastutil.longs.*;
 import java.nio.ByteBuffer;
 import java.time.Instant;
 import java.time.ZoneOffset;
@@ -18,6 +12,8 @@ import tech.tablesaw.columns.Column;
 import tech.tablesaw.columns.numbers.DoubleColumnType;
 import tech.tablesaw.columns.numbers.LongColumnType;
 import tech.tablesaw.columns.numbers.NumberColumnFormatter;
+import tech.tablesaw.selection.BitmapBackedSelection;
+import tech.tablesaw.selection.Selection;
 
 public class LongColumn extends NumberColumn<LongColumn, Long> implements CategoricalColumn<Long> {
 
@@ -114,6 +110,24 @@ public class LongColumn extends NumberColumn<LongColumn, Long> implements Catego
     return c;
   }
 
+  public Selection isIn(final long... numbers) {
+    final Selection results = new BitmapBackedSelection();
+    final LongRBTreeSet intSet = new LongRBTreeSet(numbers);
+    for (int i = 0; i < size(); i++) {
+      if (intSet.contains(getLong(i))) {
+        results.add(i);
+      }
+    }
+    return results;
+  }
+
+  public Selection isNotIn(final long... numbers) {
+    final Selection results = new BitmapBackedSelection();
+    results.addRange(0, size());
+    results.andNot(isIn(numbers));
+    return results;
+  }
+
   @Override
   public LongColumn unique() {
     final LongSet values = new LongOpenHashSet();
diff --git a/core/src/main/java/tech/tablesaw/api/NumericColumn.java b/core/src/main/java/tech/tablesaw/api/NumericColumn.java
index bdff0f65..e3165079 100644
--- a/core/src/main/java/tech/tablesaw/api/NumericColumn.java
+++ b/core/src/main/java/tech/tablesaw/api/NumericColumn.java
@@ -5,9 +5,8 @@ import static tech.tablesaw.columns.numbers.NumberPredicates.isMissing;
 import static tech.tablesaw.columns.numbers.NumberPredicates.isNotMissing;
 
 import it.unimi.dsi.fastutil.doubles.DoubleComparator;
-import it.unimi.dsi.fastutil.doubles.DoubleRBTreeSet;
 import java.text.NumberFormat;
-import java.util.Arrays;
+import java.util.Collection;
 import java.util.Optional;
 import java.util.function.BiPredicate;
 import java.util.function.DoubleBinaryOperator;
@@ -67,16 +66,10 @@ public interface NumericColumn<T extends Number>
   }
 
   @Override
-  default Selection isIn(final Number... numbers) {
-    return isIn(Arrays.stream(numbers).mapToDouble(Number::doubleValue).toArray());
-  }
-
-  @Override
-  default Selection isIn(final double... doubles) {
+  default Selection isIn(Collection<Number> numbers) {
     final Selection results = new BitmapBackedSelection();
-    final DoubleRBTreeSet doubleSet = new DoubleRBTreeSet(doubles);
     for (int i = 0; i < size(); i++) {
-      if (doubleSet.contains(getDouble(i))) {
+      if (numbers.contains(getDouble(i))) {
         results.add(i);
       }
     }
@@ -84,21 +77,13 @@ public interface NumericColumn<T extends Number>
   }
 
   @Override
-  default Selection isNotIn(final Number... numbers) {
+  default Selection isNotIn(Collection<Number> numbers) {
     final Selection results = new BitmapBackedSelection();
     results.addRange(0, size());
     results.andNot(isIn(numbers));
     return results;
   }
 
-  @Override
-  default Selection isNotIn(final double... doubles) {
-    final Selection results = new BitmapBackedSelection();
-    results.addRange(0, size());
-    results.andNot(isIn(doubles));
-    return results;
-  }
-
   @Override
   default Selection isMissing() {
     return eval(isMissing);
diff --git a/core/src/main/java/tech/tablesaw/api/ShortColumn.java b/core/src/main/java/tech/tablesaw/api/ShortColumn.java
index 916b2a62..f7a606b1 100644
--- a/core/src/main/java/tech/tablesaw/api/ShortColumn.java
+++ b/core/src/main/java/tech/tablesaw/api/ShortColumn.java
@@ -2,6 +2,7 @@ package tech.tablesaw.api;
 
 import com.google.common.base.Preconditions;
 import com.google.common.primitives.Shorts;
+import it.unimi.dsi.fastutil.ints.IntRBTreeSet;
 import it.unimi.dsi.fastutil.shorts.ShortArrayList;
 import it.unimi.dsi.fastutil.shorts.ShortArrays;
 import it.unimi.dsi.fastutil.shorts.ShortComparators;
@@ -17,6 +18,8 @@ import tech.tablesaw.columns.Column;
 import tech.tablesaw.columns.numbers.DoubleColumnType;
 import tech.tablesaw.columns.numbers.NumberColumnFormatter;
 import tech.tablesaw.columns.numbers.ShortColumnType;
+import tech.tablesaw.selection.BitmapBackedSelection;
+import tech.tablesaw.selection.Selection;
 
 public class ShortColumn extends NumberColumn<ShortColumn, Short>
     implements CategoricalColumn<Short> {
@@ -88,6 +91,24 @@ public class ShortColumn extends NumberColumn<ShortColumn, Short>
     return c;
   }
 
+  public Selection isIn(final int... numbers) {
+    final Selection results = new BitmapBackedSelection();
+    final IntRBTreeSet intSet = new IntRBTreeSet(numbers);
+    for (int i = 0; i < size(); i++) {
+      if (intSet.contains(getInt(i))) {
+        results.add(i);
+      }
+    }
+    return results;
+  }
+
+  public Selection isNotIn(final int... numbers) {
+    final Selection results = new BitmapBackedSelection();
+    results.addRange(0, size());
+    results.andNot(isIn(numbers));
+    return results;
+  }
+
   @Override
   public int size() {
     return data.size();
diff --git a/core/src/main/java/tech/tablesaw/columns/numbers/NumberFilters.java b/core/src/main/java/tech/tablesaw/columns/numbers/NumberFilters.java
index f3eaea32..6a18571b 100644
--- a/core/src/main/java/tech/tablesaw/columns/numbers/NumberFilters.java
+++ b/core/src/main/java/tech/tablesaw/columns/numbers/NumberFilters.java
@@ -19,6 +19,7 @@ import static tech.tablesaw.columns.numbers.NumberPredicates.isNonNegative;
 import static tech.tablesaw.columns.numbers.NumberPredicates.isPositive;
 import static tech.tablesaw.columns.numbers.NumberPredicates.isZero;
 
+import java.util.Collection;
 import java.util.function.BiPredicate;
 import java.util.function.DoublePredicate;
 import tech.tablesaw.api.NumericColumn;
@@ -64,13 +65,9 @@ public interface NumberFilters extends NumberFilterSpec<Selection> {
     return eval(NumberPredicates.isLessThanOrEqualTo(f));
   }
 
-  Selection isIn(Number... numbers);
+  Selection isIn(Collection<Number> numbers);
 
-  Selection isIn(double... doubles);
-
-  Selection isNotIn(Number... doubles);
-
-  Selection isNotIn(double... doubles);
+  Selection isNotIn(Collection<Number> numbers);
 
   default Selection isZero() {
     return eval(isZero);
diff --git a/core/src/main/java/tech/tablesaw/filtering/DeferredNumberColumn.java b/core/src/main/java/tech/tablesaw/filtering/DeferredNumberColumn.java
index a15c6e49..a5c97393 100644
--- a/core/src/main/java/tech/tablesaw/filtering/DeferredNumberColumn.java
+++ b/core/src/main/java/tech/tablesaw/filtering/DeferredNumberColumn.java
@@ -1,6 +1,7 @@
 package tech.tablesaw.filtering;
 
 import com.google.common.annotations.Beta;
+import java.util.Collection;
 import java.util.function.Function;
 import tech.tablesaw.api.NumericColumn;
 import tech.tablesaw.api.Table;
@@ -50,25 +51,15 @@ public class DeferredNumberColumn extends DeferredColumn
   }
 
   @Override
-  public Function<Table, Selection> isIn(Number... numbers) {
+  public Function<Table, Selection> isIn(Collection<Number> numbers) {
     return table -> table.numberColumn(name()).isIn(numbers);
   }
 
   @Override
-  public Function<Table, Selection> isIn(double... doubles) {
-    return table -> table.numberColumn(name()).isIn(doubles);
-  }
-
-  @Override
-  public Function<Table, Selection> isNotIn(Number... numbers) {
+  public Function<Table, Selection> isNotIn(Collection<Number> numbers) {
     return table -> table.numberColumn(name()).isNotIn(numbers);
   }
 
-  @Override
-  public Function<Table, Selection> isNotIn(double... doubles) {
-    return table -> table.numberColumn(name()).isNotIn(doubles);
-  }
-
   @Override
   public Function<Table, Selection> isZero() {
     return table -> table.numberColumn(name()).isZero();
diff --git a/core/src/main/java/tech/tablesaw/filtering/NumberFilterSpec.java b/core/src/main/java/tech/tablesaw/filtering/NumberFilterSpec.java
index a6a8c7e0..c8055908 100644
--- a/core/src/main/java/tech/tablesaw/filtering/NumberFilterSpec.java
+++ b/core/src/main/java/tech/tablesaw/filtering/NumberFilterSpec.java
@@ -1,6 +1,7 @@
 package tech.tablesaw.filtering;
 
 import com.google.common.annotations.Beta;
+import java.util.Collection;
 import tech.tablesaw.api.NumericColumn;
 
 @Beta
@@ -20,13 +21,9 @@ public interface NumberFilterSpec<T> extends FilterSpec<T> {
 
   T isLessThanOrEqualTo(double f);
 
-  T isIn(Number... numbers);
+  T isIn(Collection<Number> numbers);
 
-  T isIn(double... doubles);
-
-  T isNotIn(Number... numbers);
-
-  T isNotIn(double... doubles);
+  T isNotIn(Collection<Number> numbers);
 
   T isZero();
 
diff --git a/core/src/main/java/tech/tablesaw/io/ReadOptions.java b/core/src/main/java/tech/tablesaw/io/ReadOptions.java
index 3c877e40..761d310c 100644
--- a/core/src/main/java/tech/tablesaw/io/ReadOptions.java
+++ b/core/src/main/java/tech/tablesaw/io/ReadOptions.java
@@ -31,6 +31,7 @@ import com.google.common.collect.Lists;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.Reader;
 import java.net.URL;
 import java.time.format.DateTimeFormatter;
@@ -226,6 +227,10 @@ public class ReadOptions {
       this.source = new Source(stream);
     }
 
+    protected Builder(InputStreamReader reader) {
+      this.source = new Source(reader);
+    }
+
     protected Builder(Reader reader) {
       this.source = new Source(reader);
     }
diff --git a/core/src/main/java/tech/tablesaw/io/Source.java b/core/src/main/java/tech/tablesaw/io/Source.java
index c7536603..3c19a65e 100644
--- a/core/src/main/java/tech/tablesaw/io/Source.java
+++ b/core/src/main/java/tech/tablesaw/io/Source.java
@@ -34,6 +34,13 @@ public class Source {
     this.charset = charset;
   }
 
+  public Source(InputStreamReader reader) {
+    this.file = null;
+    this.reader = reader;
+    this.inputStream = null;
+    this.charset = Charset.forName(reader.getEncoding());
+  }
+
   public Source(Reader reader) {
     this.file = null;
     this.reader = reader;
@@ -72,13 +79,19 @@ public class Source {
     return inputStream;
   }
 
+  public Charset getCharset() {
+    return charset;
+  }
+
   /**
    * If cachedBytes are not null, returns a Reader created from the cachedBytes. Otherwise, returns
    * a Reader from the underlying source.
    */
   public Reader createReader(byte[] cachedBytes) throws IOException {
     if (cachedBytes != null) {
-      return new InputStreamReader(new ByteArrayInputStream(cachedBytes));
+      return charset != null
+          ? new InputStreamReader(new ByteArrayInputStream(cachedBytes), charset)
+          : new InputStreamReader(new ByteArrayInputStream(cachedBytes));
     }
     if (inputStream != null) {
       return new InputStreamReader(inputStream, charset);
diff --git a/core/src/main/java/tech/tablesaw/io/csv/CsvReadOptions.java b/core/src/main/java/tech/tablesaw/io/csv/CsvReadOptions.java
index 4088eea0..0e6ce8cb 100644
--- a/core/src/main/java/tech/tablesaw/io/csv/CsvReadOptions.java
+++ b/core/src/main/java/tech/tablesaw/io/csv/CsvReadOptions.java
@@ -17,6 +17,7 @@ package tech.tablesaw.io.csv;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.Reader;
 import java.io.StringReader;
 import java.net.URL;
@@ -103,6 +104,17 @@ public class CsvReadOptions extends ReadOptions {
     return new Builder(reader);
   }
 
+  /**
+   * This method may cause tablesaw to buffer the entire InputStream.
+   *
+   * <p>If you have a large amount of data, you can do one of the following: 1. Use the method
+   * taking a File instead of a reader, or 2. Provide the array of column types as an option. If you
+   * provide the columnType array, we skip type detection and can avoid reading the entire file
+   */
+  public static Builder builder(InputStreamReader reader) {
+    return new Builder(reader);
+  }
+
   public ColumnType[] columnTypes() {
     return columnTypes;
   }
@@ -167,6 +179,10 @@ public class CsvReadOptions extends ReadOptions {
       super(file);
     }
 
+    protected Builder(InputStreamReader reader) {
+      super(reader);
+    }
+
     protected Builder(Reader reader) {
       super(reader);
     }
diff --git a/core/src/main/java/tech/tablesaw/io/csv/CsvReader.java b/core/src/main/java/tech/tablesaw/io/csv/CsvReader.java
index e0bf51eb..7d47c533 100644
--- a/core/src/main/java/tech/tablesaw/io/csv/CsvReader.java
+++ b/core/src/main/java/tech/tablesaw/io/csv/CsvReader.java
@@ -62,7 +62,8 @@ public class CsvReader extends FileReader implements DataReader<CsvReadOptions>
     if (types == null) {
       Reader reader = source.createReader(bytesCache);
       if (source.file() == null) {
-        bytesCache = CharStreams.toString(reader).getBytes();
+        String s = CharStreams.toString(reader);
+        bytesCache = source.getCharset() != null ? s.getBytes(source.getCharset()) : s.getBytes();
         // create a new reader since we just exhausted the existing one
         reader = source.createReader(bytesCache);
       }


Test patch:
diff --git a/core/src/test/java/tech/tablesaw/api/FloatColumnTest.java b/core/src/test/java/tech/tablesaw/api/FloatColumnTest.java
index e2926a23..815025ca 100644
--- a/core/src/test/java/tech/tablesaw/api/FloatColumnTest.java
+++ b/core/src/test/java/tech/tablesaw/api/FloatColumnTest.java
@@ -18,9 +18,13 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import org.junit.jupiter.api.Test;
+import tech.tablesaw.selection.Selection;
 
 public class FloatColumnTest {
 
+  private final float[] floatColumnValues = {4, 5, 9.3f, 33.2f, 121, 77};
+  private final FloatColumn floatColumn = FloatColumn.create("fc", floatColumnValues);
+
   @Test
   public void appendFloat() {
     FloatColumn floatColumn = FloatColumn.create("floats");
@@ -45,4 +49,18 @@ public class FloatColumnTest {
     assertTrue(floatColumn.isMissing(1));
     assertEquals(4.0f, floatColumn.get(2));
   }
+
+  @Test
+  void isIn() {
+    Selection result = floatColumn.isIn(4, 40);
+    assertEquals(1, result.size());
+    assertTrue(floatColumn.where(result).contains(4f));
+  }
+
+  @Test
+  void isNotIn() {
+    Selection result = floatColumn.isNotIn(4, 40);
+    assertEquals(5, result.size());
+    assertTrue(floatColumn.where(result).contains(5f));
+  }
 }
diff --git a/core/src/test/java/tech/tablesaw/api/IntColumnTest.java b/core/src/test/java/tech/tablesaw/api/IntColumnTest.java
new file mode 100644
index 00000000..aaadfc88
--- /dev/null
+++ b/core/src/test/java/tech/tablesaw/api/IntColumnTest.java
@@ -0,0 +1,26 @@
+package tech.tablesaw.api;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+import tech.tablesaw.selection.Selection;
+
+class IntColumnTest {
+
+  private final int[] intColumnValues = {4, 5, 9, 33, 121, 77};
+  private final IntColumn intColumn = IntColumn.create("sc", intColumnValues);
+
+  @Test
+  void isIn() {
+    Selection result = intColumn.isIn(4, 40);
+    assertEquals(1, result.size());
+    assertTrue(intColumn.where(result).contains(4));
+  }
+
+  @Test
+  void isNotIn() {
+    Selection result = intColumn.isNotIn(4, 40);
+    assertEquals(5, result.size());
+    assertTrue(intColumn.where(result).contains(5));
+  }
+}
diff --git a/core/src/test/java/tech/tablesaw/api/LongColumnTest.java b/core/src/test/java/tech/tablesaw/api/LongColumnTest.java
new file mode 100644
index 00000000..29f80b3c
--- /dev/null
+++ b/core/src/test/java/tech/tablesaw/api/LongColumnTest.java
@@ -0,0 +1,26 @@
+package tech.tablesaw.api;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+import tech.tablesaw.selection.Selection;
+
+class LongColumnTest {
+
+  private final long[] longColumnValues = {4, 5, 9, 33, 121, 77};
+  private final LongColumn longColumn = LongColumn.create("sc", longColumnValues);
+
+  @Test
+  void isIn() {
+    Selection result = longColumn.isIn(4, 40);
+    assertEquals(1, result.size());
+    assertTrue(longColumn.where(result).contains(4L));
+  }
+
+  @Test
+  void isNotIn() {
+    Selection result = longColumn.isNotIn(4, 40);
+    assertEquals(5, result.size());
+    assertTrue(longColumn.where(result).contains(5L));
+  }
+}
diff --git a/core/src/test/java/tech/tablesaw/api/NumberColumnTest.java b/core/src/test/java/tech/tablesaw/api/NumberColumnTest.java
index c04fa361..4d201411 100644
--- a/core/src/test/java/tech/tablesaw/api/NumberColumnTest.java
+++ b/core/src/test/java/tech/tablesaw/api/NumberColumnTest.java
@@ -18,7 +18,6 @@ import static java.lang.Double.NaN;
 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;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static tech.tablesaw.aggregate.AggregateFunctions.median;
 import static tech.tablesaw.aggregate.AggregateFunctions.percentile;
@@ -32,6 +31,7 @@ import static tech.tablesaw.columns.numbers.NumberPredicates.isMissing;
 import com.google.common.base.Stopwatch;
 import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 import java.util.function.DoubleBinaryOperator;
@@ -201,20 +201,21 @@ public class NumberColumnTest {
   }
 
   @Test
-  public void testDoubleIsIn() {
-    int[] originalValues = new int[] {32, 42, 40, 57, 52, -2};
-    double[] inValues = new double[] {10, -2, 57, -5};
+  public void testIsIn() {
+    Number[] originalValues = {32, 42, 40, 57, 52, -2};
+    Number[] resultValues = {10.0, -2.0, 57.0, -5.0};
+    List<Number> inValues = Arrays.asList(resultValues);
 
-    DoubleColumn initial = DoubleColumn.create("Test", originalValues.length);
+    DoubleColumn initial = DoubleColumn.create("Test");
     Table t = Table.create("t", initial);
 
-    for (int value : originalValues) {
+    for (Number value : originalValues) {
       initial.append(value);
     }
 
     Selection filter = t.numberColumn("Test").isIn(inValues);
     Table result = t.where(filter);
-    assertNotNull(result);
+    assertEquals(2, result.rowCount());
   }
 
   @Test
diff --git a/core/src/test/java/tech/tablesaw/api/ShortColumnTest.java b/core/src/test/java/tech/tablesaw/api/ShortColumnTest.java
new file mode 100644
index 00000000..d11a5c20
--- /dev/null
+++ b/core/src/test/java/tech/tablesaw/api/ShortColumnTest.java
@@ -0,0 +1,26 @@
+package tech.tablesaw.api;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+import tech.tablesaw.selection.Selection;
+
+class ShortColumnTest {
+
+  private final short[] shortColumnValues = {4, 5, 9, 33, 121, 77};
+  private final ShortColumn shortColumn = ShortColumn.create("sc", shortColumnValues);
+
+  @Test
+  void isIn() {
+    Selection result = shortColumn.isIn(4, 40);
+    assertEquals(1, result.size());
+    assertTrue(shortColumn.where(result).contains((short) 4));
+  }
+
+  @Test
+  void isNotIn() {
+    Selection result = shortColumn.isNotIn(4, 40);
+    assertEquals(5, result.size());
+    assertTrue(shortColumn.where(result).contains((short) 5));
+  }
+}
diff --git a/core/src/test/java/tech/tablesaw/api/TableTest.java b/core/src/test/java/tech/tablesaw/api/TableTest.java
index 5148129c..c4234f07 100644
--- a/core/src/test/java/tech/tablesaw/api/TableTest.java
+++ b/core/src/test/java/tech/tablesaw/api/TableTest.java
@@ -14,14 +14,7 @@
 
 package tech.tablesaw.api;
 
-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;
-import static org.junit.jupiter.api.Assertions.assertSame;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
+import static org.junit.jupiter.api.Assertions.*;
 import static tech.tablesaw.aggregate.AggregateFunctions.mean;
 import static tech.tablesaw.aggregate.AggregateFunctions.stdDev;
 
@@ -744,6 +737,16 @@ public class TableTest {
     return result;
   }
 
+  @Test
+  void ambiguousMethodCallError() {
+    StringColumn s1 = StringColumn.create("1", "1", "2", "3");
+    StringColumn s2 = StringColumn.create("2", "2", "2", "2");
+    StringColumn s3 = StringColumn.create("3", "3", "2", "1");
+    IntColumn s4 = IntColumn.create("4", 1, 2, 3);
+    Table t = Table.create("t", s3, s2, s1, s4);
+    assertDoesNotThrow(() -> t.where(t.intColumn("4").isIn((int) 1, (int) 2)));
+  }
+
   @Test
   public void testToStringColumnsWithVaryingSizes() {
     IntColumn col11 = IntColumn.create("col1");
diff --git a/jsplot/src/test/java/tech/tablesaw/examples/DotPlotExample.java b/jsplot/src/test/java/tech/tablesaw/examples/DotPlotExample.java
index 19c45ea0..ed5e7521 100644
--- a/jsplot/src/test/java/tech/tablesaw/examples/DotPlotExample.java
+++ b/jsplot/src/test/java/tech/tablesaw/examples/DotPlotExample.java
@@ -30,7 +30,7 @@ public class DotPlotExample {
     IntColumn year = bush.dateColumn("date").year();
     year.setName("year");
     bush.addColumns(year);
-    bush.dropWhere(bush.intColumn("year").isIn((Number) 2001, (Number) 2002));
+    bush.dropWhere(bush.intColumn("year").isIn(2001, 2002));
     Table summary = bush.summarize("approval", AggregateFunctions.mean).by("who", "year");
 
     Layout layout2 =