toString генерирует исключение OutOfBounds - PullRequest
0 голосов
/ 03 декабря 2018

Я изучаю, как работают карты и наборы деревьев, и в настоящее время пишу свою собственную реализацию Java TreeMap.У меня проблемы с печатью имен и значений узлов в массиве объектов.Иногда метод успешно компилируется и печатается, но в большинстве случаев он генерирует исключение OutOfBoundsException.Я могу решить эту проблему, увеличив размер массива, когда я объявляю его в методе toString, но это оставляет пустую ячейку массива.

Ниже приведены методы, которые, как я считаю, связаны с ошибкой.

    private int entryArray(Object[] arr, int index, Node n) {
    if (n == null) {
        return index;
    } else {
        index = entryArray(arr, index, n.left);
        arr[index++] = new AbstractMap.SimpleEntry(n.key, n.value);
        return entryArray(arr, index, n.right);
    }
}

public class EntrySet extends SetAdapter {
    Object[] arr;

    EntrySet(Object[] arr) {
        this.arr = arr;
    }

    @Override
    public Iterator<Map.Entry<K,V>> iterator() {
        return new Iterator<Map.Entry<K,V>>() {
            int i = 0;

            @Override
            public boolean hasNext() {
                return i < arr.length;
            }

            @Override
            @SuppressWarnings("unchecked")
            public Map.Entry<K,V> next() {
                return (Map.Entry<K,V>) arr[i++];
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException("Not supported.");
            }
        };
    }
}

@Override
public String toString() {
    Object[] arr = new Object[size];
    entryArray(arr, 0, root);
    String str = java.util.Arrays.toString(arr);
    str = "{" + str.substring(1, str.length() - 1) + "}";
    return str;
}

@Override
@SuppressWarnings("unchecked")
public Set<Map.Entry<K,V>> entrySet() {
    Object[] arr = new Object[size];
    entryArray(arr, 0, root);
    return new EntrySet(arr);
}

и вот Main ()

import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.TreeMap;
import util.SearchTreeMap;



public class TestRemove {
    public static void main(String[] args) {
        TreeMap<String, Integer> java_map = new TreeMap();
        SearchTreeMap<String, Integer> my_map = new SearchTreeMap();

        String[] keys = {
                "jerry", "paul", "erin", "kevin", "helen",
                "bill", "john", "bob", "rick", "tim", "eddie",
        };

        // create random entries
        List<Map.Entry<String, Integer>> entries = new ArrayList<>();
        Random rand = new Random();
        int num_entries = 12;
        for (int i = 0; i < num_entries; i++) {
            String name = keys[rand.nextInt(keys.length)];
            int value = rand.nextInt(10);
            Integer age = value == 0 ? null : 10 + value;
            entries.add(new AbstractMap.SimpleEntry<>(name, age));
        }

        System.out.println("entries: " + entries);

        entries.forEach((entry) -> {
            java_map.put(entry.getKey(), entry.getValue());
            my_map.put(entry.getKey(), entry.getValue());
        });

        Integer value;
        int remove_index;
        String remove_key;

        // choose a random entry index, or 0 (the root)

        remove_index = rand.nextInt(entries.size());

        // remove_index = 0;

        // get the key from the chosen index
        // or, pick a key that's known to not be in the tree:

        remove_key = entries.get(remove_index).getKey();

        //remove_key = "tim";

        System.out.println("remove key = " + remove_key);

        System.out.println("\n================ java: ");
        System.out.println("before: " + java_map);
        System.out.println("size = " +  java_map.size());
        value = java_map.remove(remove_key);
        System.out.printf("remove(%s)=%s\n", remove_key, value);
        System.out.println("after: " + java_map);
        System.out.println("size = " + java_map.size());

        System.out.println("\n================= me: ");
        System.out.println("before: "+ my_map);
        System.out.println("size = "+ my_map.size());
        System.out.println("-----------");
        my_map.reverseInorderOutput();
        System.out.println("-----------");
        value = my_map.remove(remove_key);
        System.out.printf("remove(%s)=%s\n", remove_key, value);
        System.out.println("after: " + my_map);
        System.out.println("size = " + my_map.size());
        my_map.reverseInorderOutput();
    }
}

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

entries: [paul=14, bob=null, bob=14, rick=19, erin=null, tim=16, paul=12, jerry=19, john=18, jerry=11, john=16, paul=19]
remove key = paul

================ java: 
before: {bob=14, erin=null, jerry=11, john=16, paul=19, rick=19, tim=16}
size = 7
remove(paul)=19
after: {bob=14, erin=null, jerry=11, john=16, rick=19, tim=16}
size = 6

================= me: 
before: {bob=14, erin=null, jerry=11, john=16, paul=19, rick=19, tim=16}
size = 7
-----------
      tim=16
   rick=19
paul=19
            john=16
         jerry=11
      erin=null
   bob=14
-----------
remove(paul)=19
after: {erin=null, jerry=11, john=16, paul=19, rick=19, tim=16}
size = 6
      tim=16
   rick=19
paul=19
         john=16
      jerry=11
   erin=null

Process finished with exit code 0

и вот след неудачной компиляции

entries: [bob=15, jerry=18, erin=11, erin=17, helen=18, bill=15, paul=17, rick=15, helen=12, kevin=16, kevin=16, jerry=14]
remove key = erin

================ java: 
before: {bill=15, bob=15, erin=17, helen=12, jerry=14, kevin=16, paul=17, rick=15}
size = 8
remove(erin)=17
after: {bill=15, bob=15, helen=12, jerry=14, kevin=16, paul=17, rick=15}
size = 7

================= me: 
before: {bill=15, bob=15, erin=17, helen=12, jerry=14, kevin=16, paul=17, rick=15}
size = 8
-----------
         rick=15
      paul=17
         kevin=16
   jerry=14
         helen=12
      erin=17
bob=15
   bill=15
-----------
remove(erin)=17
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 7
    at util.SearchTreeMap.entryArray(SearchTreeMap.java:132)
    at util.SearchTreeMap.entryArray(SearchTreeMap.java:133)
    at util.SearchTreeMap.entryArray(SearchTreeMap.java:133)
    at util.SearchTreeMap.entryArray(SearchTreeMap.java:133)
    at util.SearchTreeMap.toString(SearchTreeMap.java:171)
    at java.lang.String.valueOf(String.java:2994)
    at java.lang.StringBuilder.append(StringBuilder.java:131)
    at prog2.TestRemove.main(TestRemove.java:76)

Process finished with exit code 1

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

Спасибо

...