статическая инициализация преобразователя Hadoop - PullRequest
1 голос
/ 04 июня 2010

У меня есть фрагмент кода, в котором я использую статический кодовый блок для инициализации переменной.

public static class JoinMap extends 
            Mapper<IntWritable, MbrWritable, LongWritable, IntWritable> {
        .......
        public static RTree rt = null;
        static {
            String rtreeFileName = "R.rtree";
            rt = new RTree(rtreeFileName);
        }
        public void map(IntWritable key, MbrWritable mbr,Context context)
                throws IOException, InterruptedException {
                            .........               
                List elements = rt.overlaps(mbr.getRect());
                .......

        }

    }

Моя проблема в том, что переменная rt во фрагменте кода выше не инициализируется.Кто-нибудь может предложить исправить или альтернативный способ инициализации переменной.Я не хочу инициализировать его внутри функции карты, поскольку это замедляет весь процесс.

Ответы [ 6 ]

2 голосов
/ 04 июня 2010

Это действительно невозможно, если сама Java не сломана.Статические инициализаторы всегда запускаются во время загрузки класса.

Возможно, что бы вы ни наблюдали, у него есть альтернативное объяснение, например, что-то устанавливает rt обратно на null.Или вы наблюдаете rt в другом статически-инициализированном выражении выше?он будет видеть null до тех пор, пока инициализация rt не закончится.

Но, тем не менее, я бы сказал, что было бы лучше переопределить метод setup() (configure() в старом API) и выполнить инициализациютам.Это случится один раз.

1 голос
/ 29 июня 2016
public static class JoinMap extends 
        Mapper<IntWritable, MbrWritable, LongWritable, IntWritable> {
    .......
    public RTree rt = null; //note that i removed static modifier

    @Override
    public void setup(Context context) throws IOException {
        //this will be executed once on each mapper before first map(..) call
        String rtreeFileName = "R.rtree";
        rt = new RTree(rtreeFileName);
    }

    public void map(IntWritable key, MbrWritable mbr,Context context)
            throws IOException, InterruptedException {
                        .........
    }

}
0 голосов
/ 29 июня 2016

вы можете переопределить метод setup () класса mapper, чтобы инициализировать что-либо в отношении функции map. Этот метод setup () вызывается только один раз, в начале каждого преобразователя, и поэтому он не замедляет процесс преобразователя

0 голосов
/ 24 июня 2013

что делать, если мы не объявляем статический блок и просто пишем.

public static RTree rt =  new RTree(rtreeFileName);

поскольку переменная является статической, она будет инициализирована один раз при загрузке класса в память?

0 голосов
/ 05 июня 2010

Я не эксперт по Java, но, похоже, у вас есть два "статических" назначения для переменной rt: У вас есть:

общедоступная статическая RTree rt = ноль ;

И

rt = новое RTree (rtreeFileName) ;

В каком порядке выполняются эти назначения?

Попробуйте вместо этого и посмотрите, поможет ли это

    public static final RTree rt = new RTree("R.rtree");

Насколько мне известно о Java, это гарантирует, что у вас будет только одно задание.

0 голосов
/ 04 июня 2010

Есть ли причина, по которой вы не хотите инициализировать rt следующим образом?:

public static RTree rt = new RTree("R.rtree");
...