KvCoder extends StructuredCoder<KV<K, V>> { public static <K, V> KvCoder<K, V> of(Coder<K> keyCoder, Coder<V> valueCoder) { return new KvCoder<>(keyCoder, valueCoder); } private  KvCoder(Coder<K> keyCoder, Coder<V> valueCoder); static KvCoder<K, V> of(Coder<K> keyCoder, Coder<V> valueCoder); Coder<K> getKeyCoder(); Coder<V> getValueCoder(); @Override void encode(KV<K, V> kv, OutputStream outStream); @Override void encode(KV<K, V> kv, OutputStream outStream, Context context); @Override KV<K, V> decode(InputStream inStream); @Override KV<K, V> decode(InputStream inStream, Context context); @Override List<? extends Coder<?>> getCoderArguments(); @Override void verifyDeterministic(); @Override boolean consistentWithEquals(); @Override Object structuralValue(KV<K, V> kv); @Override boolean isRegisterByteSizeObserverCheap(KV<K, V> kv); @Override void registerByteSizeObserver(KV<K, V> kv, ElementByteSizeObserver observer); @Override TypeDescriptor<KV<K, V>> getEncodedTypeDescriptor();  }
@Test @SuppressWarnings("rawtypes") public void testDecodeEncodeEqual() throws Exception { for (AnyCoderAndData keyCoderAndData : TEST_DATA) { Coder keyCoder = keyCoderAndData.coderAndData.coder; for (Object key : keyCoderAndData.coderAndData.data) { for (AnyCoderAndData valueCoderAndData : TEST_DATA) { Coder valueCoder = valueCoderAndData.coderAndData.coder; for (Object value : valueCoderAndData.coderAndData.data) { CoderProperties.coderDecodeEncodeEqual( KvCoder.of(keyCoder, valueCoder), KV.of(key, value)); } } } } }
@Test public void testCoderIsSerializableWithWellKnownCoderType() throws Exception { CoderProperties.coderSerializable( KvCoder.of(GlobalWindow.Coder.INSTANCE, GlobalWindow.Coder.INSTANCE)); }