#java #hadoop #arraylist #treemap
#java #hadoop #список массивов #древовидная карта
Вопрос:
У меня есть древовидная карта списков массивов. Мне нужно проверить каждый список на соответствие элементов. Мой код работает, за исключением того, что он только проверяет массивы на соответствие единицам <= самому себе. Остальные массивы отслеживаются нормально. Я бы предположил, что это глупая ошибка, которую я пропускаю, но..
ArrayList<Integer> currentArray;
ArrayList<Integer> compareArray;
//Setting user friend list
//cycle users "i"
for(int i = 1; i <= treemap.size(); i ){
currentArray = treemap.get(i);
//cycle user "k"
for(int k=1; k <= treemap.size(); k ){
//if(i!=k){ Put back in once working
compareArray = treemap.get(k);
//cylce "k"s movie list
for(int l=0; l < compareArray.size(); l ){
if(currentArray.contains(compareArray.get(l))){
if (treemap2.containsKey(i)){
ArrayList<Integer> list3 = treemap2.get(i);
list3.add(k);
treemap2.remove(i);
treemap2.put(i, list3);
}
if (!treemap2.containsKey(i)){
ArrayList<Integer> list4 = new ArrayList<Integer>();
list4.add(k);
treemap2.put(i, list4);
}
}
}
}
}
//Create string of friends
for(ArrayList<Integer> x: treemap2.values()){
str2 = Integer.toString(x.get(0));
for (int i = 1; i < x.size(); i )
{
str2 = str2 "," Integer.toString(x.get(i)) ;
}
}
context.write(key, new Text(str2));
Мне все еще нужно исправить ключ, это просто и в любом случае не используется в окончательной программе.
Я должен получать 1 1,1,1,2,2 2 1,1,2,2,2 3 2,3,3,3
Вместо этого я получаю 1 1,1,1 2 1,1,2,2,2 3 2,3,3,3
В любом случае, заранее благодарю вас. Примечание стороны, выполнение приведенного ниже дает мне именно то, что я хочу… За исключением того, что в нем не учитывается последний массив ….!!
//cycle current array "i"
for(int i = 1; i < treemap.size(); i ){
currentArray = treemap.get(i);
//cycle compare array "k"
for(int k=1; k <= treemap.size(); k ){
if(i!=k){ //
compareArray = treemap.get(k);
//cylce array element in compare "l"
for(int l=0; l < compareArray.size(); l ){
if(currentArray.contains(compareArray.get(l))){
if (treemap2.containsKey(i)){
ArrayList<String> list3 = treemap2.get(i);
list3.add(k ":" compareArray.get(l));
treemap2.remove(i);
treemap2.put(i, list3);
}
if (!treemap2.containsKey(i)){
ArrayList<String> list4 = new ArrayList<String>();
list4.add(k ":" compareArray.get(l));
treemap2.put(i, list4);
}
}
}
}
}
}
1 2105
1 1953
1 1339
2 2105
2 1321
2 1339
3 1321
3 1544
3 1222
Комментарии:
1. Я бы проделал это с помощью своего отладчика, если бы это было завершено, но в нем отсутствует код в начале и в конце. Например, я не вижу, как объявляется treemap. Можете ли вы опубликовать полный список кода?
2. Я добавил это, но.. Он предназначен для запуска в hadoop.
3. Не могли бы вы также предоставить мне список значений в каждом массиве вашей treemap, который вы использовали для своего теста?
4. Фактические данные, которые у меня есть, намного больше, но значительно усеченные данные: 1 2105 1 1953 1 1339 2 2105 2 1321 2 1339 3 1321 3 1544 3 1222
5. Я понимаю, что 🙂 этого достаточно для проверки ожидаемых входных и выходных данных.
Ответ №1:
Я немного не уверен в некоторых ваших определениях переменных и данных, потому что между двумя проводками была некоторая разница. Однако я создал автономную Java-программу, которая изолирует ваш алгоритм и использует фиктивные данные для его тестирования. Ниже приведена вся программа, она довольно маленькая.
Это был бы мой общий подход к использованию сочетания трассировки и точки останова отладчика, чтобы иметь возможность видеть результаты и проверять все переменные в ключевых точках.
Вы могли бы исправить любые неправильные предположения, которые я сделал о типах данных.
Я надеюсь, что это поможет.
package com.example.hadoop;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.TreeMap;
/**
* I took your original code posting (which differs somewhat from the second
* snippet) and I converted it into a stand alone Java program with mock test
* data.
*
* This program would be my starting point to finding the logic error.
*
* My approach was to (1) isolate your algorithm, (2) mock out a minimal set of
* input data to test just the algorithm, and (3) step through with the debugger
* and/or use some trace statements.
*
* I made assumptions about variable definitions based on the code and
* information provided since I could not see all the actual definitions.
*
* Some of your data types differ between your two code fragments so I was a bit
* unsure about that.
*
* I may be wrong on some of the variable definitions so modify these as needed.
*
* You mentioned that:
*
* Expected result: 1 1,1,1,2,2 2 1,1,2,2,2 3 2,3,3,3
*
* Actual result: 1 1,1,1 2 1,1,2,2,2 3 2,3,3,3
*
* Massively truncated test data: 1 2105 1 1953 1 1339 2 2105 2 1321 2 1339 3
* 1321 3 1544 3 1222
*/
public class HadoopTestApp {
/*
* Mock test variables.
*/
ArrayList<Integer> datalist1 = new ArrayList<Integer>(Arrays.asList(2105, 1953, 1339));
ArrayList<Integer> datalist2 = new ArrayList<Integer>(Arrays.asList(2105, 1321, 1339));
ArrayList<Integer> datalist3 = new ArrayList<Integer>(Arrays.asList(1321, 1544, 1222));
TreeMap<Integer, ArrayList<Integer>> treemap = new TreeMap<Integer, ArrayList<Integer>>();
TreeMap<Integer, ArrayList<Integer>> treemap2 = new TreeMap<Integer, ArrayList<Integer>>();
String str2 = "";
/**
* Use the default constructor to complete the initialization of mock test
* variables.
*/
public HadoopTestApp() {
treemap.put(1, datalist1);
treemap.put(2, datalist2);
treemap.put(3, datalist3);
}
/**
* Bootstrap the test.
*
* @param args Command line arguments are not currently used.
*/
public static void main(String[] args) {
new HadoopTestApp().run(args);
}
/**
* If you prefer to trace variables manually. Or you can set some breakpoints
* and inspect variables in the debugger.
*/
public void doTrace(String label, Object o) {
System.out.print(label ": ");
System.out.println(o);
}
/**
* Run the test of Hooch's algorithm.
*
* @param args Command line arguments are not currently used.
*/
public void run(String[] args) {
doTrace("treemap", treemap); // NEW
ArrayList<Integer> currentArray;
ArrayList<Integer> compareArray;
// Setting user friend list
// cycle users "i"
for (int i = 1; i <= treemap.size(); i ) {
currentArray = treemap.get(i);
// cycle user "k"
for (int k = 1; k <= treemap.size(); k ) {
// if(i!=k){ Put back in once working
compareArray = treemap.get(k);
// cylce "k"s movie list
for (int l = 0; l < compareArray.size(); l ) {
if (currentArray.contains(compareArray.get(l))) {
// NEW I set a debugger breakpoint on this line to inspect all variables
if (treemap2.containsKey(i)) {
ArrayList<Integer> list3 = treemap2.get(i);
list3.add(k);
treemap2.remove(i);
treemap2.put(i, list3);
doTrace("contains key, treemap2", treemap2); // NEW
}
if (!treemap2.containsKey(i)) {
ArrayList<Integer> list4 = new ArrayList<Integer>();
list4.add(k);
treemap2.put(i, list4);
doTrace("does not contain key, treemap2", treemap2); // NEW
}
}
}
}
}
// Create string of friends
for (ArrayList<Integer> x : treemap2.values()) {
str2 = Integer.toString(x.get(0));
for (int i = 1; i < x.size(); i ) {
str2 = str2 "," Integer.toString(x.get(i));
}
doTrace("in loop str2", str2); // NEW
}
// context.write(key, new Text(str2));
doTrace("context.write str2", str2); // NEW
}
}
Комментарии:
1. Итак, единственное реальное различие здесь — «i <= treemap.size()» против «i <treemap.size()», и хотя я согласен, что так и должно быть , это не работает. В вашем примере он выполняет поиск только в массиве для самого себя. Итак 1[1], 2[1,2], 3[1,2,3]. с помощью «i<» я получаю 1[1,2,3], 2[1,2,3], 3 никогда не запускается..
2. Мой пример — это просто оболочка вокруг кода вашего исходного вопроса, и идея состоит в том, чтобы иметь отправную точку для уточнения моих предположений о типах данных и входных данных. Это не исправление, это был бы просто мой подход к определению, где условная логика не работает должным образом, используя сочетание точек останова трассировки и отладки.
3. Да, алгоритм был правильным. Просто возникают проблемы с его распечаткой. Все еще возникает проблема, но гораздо ближе. Спасибо.