Apache Giraph/Hadoop: итерация пользовательского ArrayWritable

Я думал, что это будет просто реализовать, но это начинает доставлять неудобства.

У меня есть подкласс ArrayWritable так:

public class VertexDistanceArrayWritable extends ArrayWritable {
    public VertexDistanceArrayWritable() {
        super(VertexDistanceWritable.class);
    }
    public VertexDistanceArrayWritable(VertexDistanceWritable[] v) {
        super(VertexDistanceWritable.class, v);
    }
}

И Writable подкласс так:

public class VertexDistanceWritable implements Writable {

    //Implements write, readFields, and some custom functions that aren't used yet

}

В моей вычислительной функции Giraph сообщения принадлежат VertexDistanceArrayWritable. Я хочу перебирать каждое сообщение VertexDistanceWritable (VertexDistanceArrayWritable). Вот моя вычислительная функция:

@Override
public void compute(Vertex<Text, MapWritable, FloatWritable> vertex,
    Iterable<VertexDistanceArrayWritable> messages) throws IOException {

    for(VertexDistanceArrayWritable message : messages) {
        for(VertexDistanceWritable distEntry : message) {
            //Do stuff with distEntry
        }
    }

    //do other stuff

    vertex.voteToHalt();
}

Когда я компилирую код, я получаю эту ошибку:

for-each not applicable to expression type
    for(VertexDistanceWritable distEntry : message) {

  required: array or java.lang.Iterable
  found:    VertexDistanceArrayWritable

Итак, теперь у меня есть проблема. Я хочу перебрать подкласс arrayWritable.

Я пробовал следующее:

  • Измените эту строку на for(VertexDistanceWritable distEntry : message.toArray()), которая говорит мне, что for-each неприменим для типа Object (требуется: массив или java.lang.Iterable, найдено: Object).

  • Измените эту строку на for(VertexDistanceWritable distEntry : message.get() ), что даст мне error: incompatible types -- required: VertexDistanceWritable, found: Writable. Это самая странная проблема — VertexDistanceWritable расширяет Writable, разве это не должно работать нормально?

  • Пишу свою собственную функцию "get_foo()" для VertexDistanceWritable, которая возвращает значения в виде VertexDistanceWritable[]. Конечно, значения являются частными и не имеют функции получения в соответствии с документацию, кроме get(), с которой у меня уже возникли проблемы

Мне просто нужен способ перебора моего класса VertexDistanceArrayWritable. Возможно ли это вообще в Hadoop? Это должно быть, верно? Я должен иметь возможность перебирать кучу элементов, которые я сделал в массиве, не так ли? Кажется, что это чертовски базовые вещи.


person user3760657    schedule 27.05.2016    source источник


Ответы (1)


Примерно через 30 минут экспериментов и гугления я нашел подсказку здесь. Вроде сырный, но, похоже, компилируется правильно. В основном просто используйте Writable, а затем приведите его к моему пользовательскому writable.

for(VertexDistanceArrayWritable message : messages) {
    for(Writable distWritable : message.get()) {
        vertexDistanceWritable distEntry = (VertexDistanceWritable) distWritable;
        //do other stuff
    }
}

Я еще не подтвердил, работает ли он правильно, я обновлю и подтвержу свой ответ, когда смогу убедиться, что он работает.

редактировать: это работает. Может потребоваться конструктор копирования, так как у меня был один для VertexDistanceWritable, но я никогда не проверял это.

person user3760657    schedule 27.05.2016