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