    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      public void readFields(DataInput in) throws IOException {
    092        values = new Writable[in.readInt()];          // construct values
    093        for (int i = 0; i < values.length; i++) {
    094          Writable value = WritableFactories.newInstance(valueClass);
    095          value.readFields(in);                       // read a value
    096          values[i] = value;                          // store it in values
    097        }
    098      }
    099
    100      public void write(DataOutput out) throws IOException {
    101        out.writeInt(values.length);                 // write values
    102        for (int i = 0; i < values.length; i++) {
    103          values[i].write(out);
    104        }
    105      }
    106
    107    }
    108