001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package org.apache.hadoop.io; 020 021 import java.io.*; 022 import java.lang.reflect.Array; 023 024 import org.apache.hadoop.classification.InterfaceAudience; 025 import org.apache.hadoop.classification.InterfaceStability; 026 027 /** 028 * A Writable for arrays containing instances of a class. The elements of this 029 * writable must all be instances of the same class. If this writable will be 030 * the input for a Reducer, you will need to create a subclass that sets the 031 * value to be of the proper type. 032 * 033 * For example: 034 * <code> 035 * public class IntArrayWritable extends ArrayWritable { 036 * public IntArrayWritable() { 037 * super(IntWritable.class); 038 * } 039 * } 040 * </code> 041 */ 042 @InterfaceAudience.Public 043 @InterfaceStability.Stable 044 public class ArrayWritable implements Writable { 045 private Class<? extends Writable> valueClass; 046 private Writable[] values; 047 048 public ArrayWritable(Class<? extends Writable> valueClass) { 049 if (valueClass == null) { 050 throw new IllegalArgumentException("null valueClass"); 051 } 052 this.valueClass = valueClass; 053 } 054 055 public ArrayWritable(Class<? extends Writable> valueClass, Writable[] values) { 056 this(valueClass); 057 this.values = values; 058 } 059 060 public ArrayWritable(String[] strings) { 061 this(UTF8.class, new Writable[strings.length]); 062 for (int i = 0; i < strings.length; i++) { 063 values[i] = new UTF8(strings[i]); 064 } 065 } 066 067 public Class getValueClass() { 068 return valueClass; 069 } 070 071 public String[] toStrings() { 072 String[] strings = new String[values.length]; 073 for (int i = 0; i < values.length; i++) { 074 strings[i] = values[i].toString(); 075 } 076 return strings; 077 } 078 079 public Object toArray() { 080 Object result = Array.newInstance(valueClass, values.length); 081 for (int i = 0; i < values.length; i++) { 082 Array.set(result, i, values[i]); 083 } 084 return result; 085 } 086 087 public void set(Writable[] values) { this.values = values; } 088 089 public Writable[] get() { return values; } 090 091 @Override 092 public void readFields(DataInput in) throws IOException { 093 values = new Writable[in.readInt()]; // construct values 094 for (int i = 0; i < values.length; i++) { 095 Writable value = WritableFactories.newInstance(valueClass); 096 value.readFields(in); // read a value 097 values[i] = value; // store it in values 098 } 099 } 100 101 @Override 102 public void write(DataOutput out) throws IOException { 103 out.writeInt(values.length); // write values 104 for (int i = 0; i < values.length; i++) { 105 values[i].write(out); 106 } 107 } 108 109 } 110