Erste Schritte IndexOutOfBounce abfangen?

Loddakwin

Aktives Mitglied
Hallo Leute,
wie der Titel schon verrät, bekomme ich eine IndexOutOfBounce. Ich habe versucht das mittels if -else zu verhindern, jedoch geht er nicht in den else Teil. Wäre nett, wenn mir hier wer weiterhelfen könnte.

Code:
for(int l = 0; l < allLeaves; l++) {
        for(int j = 0; j < degree(); j++) {
            if(leaves.get(l).key(j) != null) {
                System.out.print(leaves.get(l).key(j) + ":" + 0 + ":");
            } else {
                break;
            }
        }
        System.out.println();
    }

LG
 
am besten ist es immer über die Größe des Array zu iterieren

Code:
for(int i = 0; i < leaves.length; i++)
    for(int j = 0; j < leaves[i].length; j++

Dann kannst Du sicher sein das du immer innerhalb des Arrays bleibst.

Gruß

Claus
 
Ich hab vergessen zu sagen, dass es sich hier um eine Liste mit Objekten handelt. In dieser Liste sind Objekte mit x Werten und ich versuche hier über die Werte zu iterieren. In den letzten zwei Objekten sind jedoch nicht gleich viele Werte wie in den anderen. Das heißt length bzw size() hilft mir nur in der ersten Schleife.(allLeaves = leaves.size() - 1)

Daher muss ich irgendwie prüfen, ob es null ist oder nicht. Wenn das geht?

Trotzdem danke für deine schnelle Antwort.
 
Du überprüfst es doch bereits auf null. Deine Exception ist auch keine NullPointerException sondern eine IndexOutOfBounceException. Hast du Informationen hierzu?
 
Ich muss einen B+Baum implementieren. In der Liste sind sozusagen Blätter des Baumes abgespeichert. Wie sehen die Objekte aus? Was meinst du damit? In den Objekten sind Zahlen bzw Suchschlüssel und über diese versuche ich zu iterieren.
 
Zeig doch mal die key() Funktion oder besser gleich die ganze Klasse in der diese definiert ist. Ich verstehe nämlich immer noch nicht was das werden soll wenn es fertig ist. Und was macht eigentlich degree()?
 
Wenn das nicht geht, dann weiß ich nicht wie ich über die Werte iterieren soll, da es Objekte mit unterschiedlicher Anzahl an Werten gibt. Die key() Funktion gibt dir alle Suchschlüssel, die als input gegeben wurden, zurück.
 
Es gibt keine Objecte mit unterschiedlicher Anzahl an Werten! Es gibt Objekte mit unterschiedlicher Anzahl an Attributen aber ich glaube nicht das Du das meinst. Es gibt nur Listen, Sets und Arrays die unterschiedliche Anzahl an Elementen haben können. Und ja, das sind alles Objekte. Aber eben bestimmte. Deswegen will ich wissen was dein Object denn nun eigentlich ist bzw wie es aufgebaut ist. Aber solange du uns keinen Code zeigst können wir hier auch nur rumraten.
 
Code:
package bptree;

// java imports
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

/**
* A generic implementation of a B+ tree that is supposed to support bulk
* loading. It uses the <tt>BPNode</tt> class to stored the keys and children.
*
* @param <Key> the type of the keys stored in this B+ tree. This type has to
*  implement the <tt>Comparable</tt> interface.
*
* @see BPNode
*/
public class BPTree<Key extends Comparable<Key>> {
    /**
   * Constructs an empty B+ tree of a specified node degree, i.e., m.
   *
   * @param degree the node degree of this B+ tree node (i.e., m)
   */
  public BPTree(final int degree) {
    this.degree = degree;
  }

  // public methods

  /**
   * Retrieves the root node of this B+ tree.
   *
   * @return the root node of this B+ tree
   */
  public BPNode<Key> root() {
    return root;
  }

  /**
   * Retrieves the degree of this B+ tree.
   *
   * @return the degree of this B+ tree
   */
  public int degree() {
    return degree;
  }

  /**
   * Construct a B+ tree bottom-up.
   *
   * @param keys a list of keys that are bulk loaded into the B+ tree
   *
   * @return a sorted list of all created nodes (sorted with respect to the node
   *  identifier)
   */
  public List<BPNode<Key>> loadBulk(final List<Key> keys) {
    // IMPORTANT: no need to modify this method

    // list of all nodes created in the process
    List<BPNode<Key>> nodeList = new ArrayList<BPNode<Key>>();

    // deal with trivial cases
    if ((keys == null) || keys.isEmpty()) {
      return nodeList;
    }

    // sort keys
    Collections.sort(keys);

    // build the leaf level based on the given keys
    List<BPNode<Key>> leaves = buildLeafLevel(keys);

    // append leaves
    nodeList.addAll(leaves);

    // assign the list of leaf nodes as the current "top level" (since it is the
    // only level at this point in time)
    List<BPNode<Key>> topLevelNodes = leaves;

    // construct additional inner levels until there is only one node in the
    // current "top level" of the B+ tree, i.e., the root node has been built
    // and we can stop constructing additional tree levels
    while (topLevelNodes.size() > 1) {
      // build next higher level based on the currently assigned "top level" of
      // the B+ tree and assign the resulting level as the new "top level"
      // this is done as long as we have more than one (inner) node in the
      // current "top level"
      topLevelNodes = buildInnerLevel(topLevelNodes);

      // append newly constructed level
      nodeList.addAll(topLevelNodes);
    }

    // just to make sure that the "top level" has at least one element
    if (topLevelNodes.size() > 0) {
      // assign the first element of the final "top level" as root node
      // if the B+ tree is built correctly, the first element of topLevelNodes
      // is the -only- node in the list
      root = topLevelNodes.get(0);
    }

    // return sorted list of nodes (sorted with respect to the node identifier)
    return nodeList;
  }

  /**
   * Builds a valid leaf level of this B+ tree with the minimal number of leaf
   * nodes for the specified list of keys. This method returns a sorted list of
   * the leaf nodes created in the process (sorted with respect to the keys in
   * the nodes). The children in a leaf node are supposed to be <tt>null</tt>.
   *
   * @param keys a sorted list of keys that are bulk loaded into the B+ tree
   *
   * @return a sorted list of all leaf nodes created in the process, or
   *  <tt>null</tt> if there are no keys to load
   */
  private List<BPNode<Key>> buildLeafLevel (final List<Key> keys) {
    // deal with trivial cases
    if ((keys == null) || keys.isEmpty()) {
      return null;
    }

    List<BPNode<Key>> leaves = new ArrayList<BPNode<Key>>();
   
    int allKeys = keys.size();
    int searchKeysSpace = degree() - 1;
    BPNode<Key> leaf = null;
    int i = 0;
   
    while(i < allKeys) {
            leaf = new BPNode<Key>(degree());
           
            for(int j = 0; j < searchKeysSpace; j++) {
                if(i == allKeys)
                    break;
               
                leaf.addKey(keys.get(i));
                i++;
            }
           
            leaves.add(leaf);
           
        }
   
    double checkAnz = degree() - 1;
    double searchKeyMinAnz = Math.ceil(checkAnz/2);
    int allLeaves = leaves.size() - 1;
    BPNode<Key> last = leaves.get(allLeaves);
    BPNode<Key> beforethelast = leaves.get(allLeaves - 1);
    int removeKeySize = (leaves.get(allLeaves - 1).keys().size()) - 1;
   
    while(leaves.get(allLeaves).keys().size() < (int) searchKeyMinAnz) {
            last.addKey(0,beforethelast.key(removeKeySize));
            beforethelast.removeLastKey();
            removeKeySize--;
    }
   
    for(int l = 0; l < allLeaves; l++) {
        for(int j = 0; j < degree(); j++) {
            if(leaves.get(l).key(j) != null) {
                System.out.print(leaves.get(l).key(j) + ":" + 0 + ":");
            } else {
                break;
            }
        }
        System.out.println();
    }
   
    return leaves;
  }

  /**
   * Builds a valid inner level of this B+ tree with the minimal number of inner
   * nodes for the specified list of child nodes. This method returns a sorted
   * list of the inner nodes created in the process (sorted with respect to the
   * keys in the nodes). The children in an inner node are supposed to point
   * to the respective child nodes.
   *
   * @param children a sorted list of child nodes for which the next inner level
   *  is built
   *
   * @return a sorted list of all inner nodes created in the process, or
   *  <tt>null</tt> if there are no children to connect
   */
  private List<BPNode<Key>> buildInnerLevel (final List<BPNode<Key>> children) {
    // deal with trivial cases
    if ((children == null) || children.isEmpty()) {
      return null;
    }

    List<BPNode<Key>> currentLevel = new ArrayList<BPNode<Key>>();
   
    List<BPNode<Key>> temp;
   
   
    for(int i = 1; i < children.size(); i++) {
        //temp = children.get(i).;   
    }
   
    //System.out.print(temp);
   
    return currentLevel;
  }

  /**
   * Retrieves the smallest key in the specified branch of this B+ tree, i.e.,
   * the leftmost key of the leftmost branch with respect to the specified node.
   *
   * @param node the node that represents the subroot of the branch for which
   *  the smallest key should be found
   *
   * @return the smallest key of the branch that has <tt>node</tt> as (sub)root
   */
  private Key smallestKey(final BPNode<Key> node) {
    // IMPORTANT: no need to modify this method

    BPNode<Key> currentNode = node;

    // iterate until the leaf level is reached and following the leftmost
    // child on each traversed inner level (to reach the leftmost leaf of the
    // B+ tree branch that is rooted at node)
    while (!currentNode.isLeaf()) {
      currentNode = currentNode.child(0);
    }

    // return the first key of the leftmost leaf of the specified branch
    return currentNode.key(0);
  }

  // private

  // the degree of this B+ tree
  private final int degree;
  // the root node of this B+ tree
  private BPNode<Key> root = null;
}
 
Code:
package bptree;

// java imports
import java.util.List;
import java.util.ArrayList;

/**
* <p>
* <strong>IMPORTANT:</strong> Do not modify this class. When you submit your
* code, all changes to this file are discarded automatically. Hence, it may
* happen that you program is not working on the submission system.
* </p>
* <p>
* A simple implementation of a B+ tree node that has an identifier, a node
* degree, a list of keys (of a specified type), and a list of children to other
* B+ tree nodes.
* </p>
*
* @param <Key> the type of the keys stored in this B+ tree node. This type has
*  to implement the <tt>Comparable</tt> interface.
*/
public class BPNode<Key extends Comparable<Key>> {
  /**
   * Constructs an empty B+ tree node of a specified degree.
   *
   * @param degree the node degree of this B+ tree node (i.e., m)
   */
  public BPNode(final int degree) {
    // consecutive node ids
    id = ++globalNodeId;
    this.degree = degree;

    // empty key and children lists
    keys = new ArrayList<Key>();
    children = new ArrayList<BPNode<Key>>();
  }

  /**
   * Retrieves the unique identifier of this B+ tree node.
   *
   * @return the unique identifier of this B+ tree node
   */
  public int id() {
    return id;
  }

  /**
   * Retrieves the degree of this B+ tree node.
   *
   * @return the degree of this B+ tree node
   */
  public int degree() {
    return degree;
  }

  /**
   * Retrieves the list of keys stored in this B+ tree node.
   *
   * @return the list of keys stored in this B+ tree node
   */
  public List<Key> keys() {
    return keys;
  }

  /**
   * Retrieves the list of children stored in this B+ tree node.
   *
   * @return the list of children stored in this B+ tree node
   */
  public List<BPNode<Key>> children() {
    return children;
  }

  /**
   * Retrieves the type of a B+ tree node, i.e., is it a leaf node or not.
   *
   * @return <tt>true</tt> if this B+ tree node is a leaf, <tt>false</tt>
   *  otherwise
   */
  public boolean isLeaf() {
    // we have to deal with this case somehow
    if (children.isEmpty()) {
      return true;
    }

    return (children.get(0) == null);
  }

  /**
   * Retrieves a reference to the child at a specified index (0-based) of this
   * B+ tree node. Be aware that this method does not perform any range checks
   * for the given index.
   *
   * @param index the index of the child to retrieve (0-based)
   *
   * @return the reference to the child at the specified index of this B+ tree
   *  node
   *
   * @throws IndexOutOfBoundsException
   */
  public BPNode<Key> child(final int index) {
    return children.get(index);
  }

  /**
   * Retrieves a reference to the first child aof this B+ tree node if it
   * exists.
   *
   * @return the reference to the first child of this B+ tree node if it exists,
   *  <tt>null</tt> otherwise
   */
  public BPNode<Key> firstChild() {
    try {
      return child(0);
    } catch (IndexOutOfBoundsException ioobe) {
      return null;
    }
  }

  /**
   * Retrieves the key at a specified index (0-based) of this B+ tree node. Be
   * aware that this method does not perform any range checks for the given
   * index.
   *
   * @param index the index of the key to retrieve (0-based)
   *
   * @return the key at the specified index of this B+ tree node
   *
   * @throws IndexOutOfBoundsException if the index is out of range
   *  (<tt>index < 0 || index > size()</tt>)
   */
  public Key key(final int index) {
    return keys.get(index);
  }

  /**
   * Adds the specified key at a specified index (0-based) of this B+ tree node.
   * Be aware that this method does not perform any range checks for the given
   * index.
   *
   * @param index the index the specified key is added at (0-based)
   *
   * @throws IndexOutOfBoundsException if the index is out of range
   *  (<tt>index < 0 || index > size()</tt>)
   */
  public void addKey(final int index, final Key key) {
    keys.add(index, key);
  }

  /**
   * Appends the specified key to this B+ tree node. This is equivalent to the
   * call <tt>addKey(keys().size(), key)</tt>.
   *
   * @throws IndexOutOfBoundsException if the index is out of range
   *  (<tt>index < 0 || index > size()</tt>)
   */
  public void addKey(final Key key) {
    addKey(keys.size(), key);
  }

  /**
   * Adds the specified child at a specified index (0-based) of this B+ tree
   * node. Be aware that this method does not perform any range checks for the
   * given index.
   *
   * @param index the index the specified child is added at (0-based)
   *
   * @throws IndexOutOfBoundsException if the index is out of range
   *  (<tt>index < 0 || index > size()</tt>)
   */
  public void addChild(final int index, final BPNode<Key> child) {
    children.add(index, child);
  }

  /**
   * Appends the specified child to this B+ tree node. This is equivalent to the
   * call <tt>addChild(children().size(), child)</tt>.
   *
   * @throws IndexOutOfBoundsException if the index is out of range
   *  (<tt>index < 0 || index > size()</tt>)
   */
  public void addChild(final BPNode<Key> child) {
    addChild(children.size(), child);
  }

  /**
   * Removes the key at a specified index (0-based) of this B+ tree node. Be
   * aware that this method does not perform any range checks for the given
   * index.
   *
   * @param index the index of the key to be removed (0-based)
   *
   * @return the removed key
   *
   * @throws IndexOutOfBoundsException if the index is out of range
   *  (<tt>index < 0 || index > size()</tt>)
   */
  public Key removeKey(final int index) {
    return keys.remove(index);
  }

  /**
   * Removes the last key of this B+ tree node. This is equivalent to the call
   * <tt>removeKey(keys().size() - 1)</tt>.
   *
   * @return the removed key if it existed, <tt>null</tt> otherwise
   *
   * @throws IndexOutOfBoundsException if the index is out of range
   *  (<tt>index < 0 || index > size()</tt>)
   */
  public Key removeLastKey() {
    try {
      return removeKey(keys.size() - 1);
    } catch (IndexOutOfBoundsException ioobe) {
      return null;
    }
  }

  /**
   * Removes the child at a specified index (0-based) of this B+ tree node. Be
   * aware that this method does not perform any range checks for the given
   * index.
   *
   * @param index the index of the child to be removed (0-based)
   *
   * @return the removed child
   *
   * @throws IndexOutOfBoundsException if the index is out of range
   *  (<tt>index < 0 || index > size()</tt>)
   */
  public BPNode<Key> removeChild(final int index) {
    return children.remove(index);
  }

  /**
   * Removes the last child of this B+ tree node. This is equivalent to the
   * call <tt>removeChild(children().size() - 1)</tt>.
   *
   * @return the removed child if it existed, <tt>null</tt> otherwise
   *
   * @throws IndexOutOfBoundsException if the index is out of range
   *  (<tt>index < 0 || index > size()</tt>)
   */
  public BPNode<Key> removeLastChild() {
    try {
      return removeChild(children.size() - 1);
    } catch (IndexOutOfBoundsException ioobe) {
      return null;
    }
  }

  /**
   * <p>
   * Overridden <tt>toString</tt> method to print this B+ tree node.
   * </p>
   *
   * @return a string representing this B+ tree node
   *
   * @see Object
   */
  @Override
  public String toString() {
    String str = new String();

    // append node identifier
    str += id() + ":";

    // append keys and children
    for (int i = 0; i < keys.size(); ++i) {
      BPNode<Key> currentNode = null;
      try {
        currentNode = children.get(i);
      } catch(IndexOutOfBoundsException ioobe) {
        System.err.println("[WARNING] BPNode has too few child pointers (" + children.size() +
          ") for its number of keys (" + keys.size() + ")");
        return "";
      }
      str += (currentNode == null ? "0" : currentNode.id()) + ":";
      str += keys.get(i) + ":";
    }

    // append last child
    BPNode<Key> lastNode = null;
    try {
      lastNode = children.get(children.size() - 1);
    } catch(IndexOutOfBoundsException ioobe) {
      System.err.println("[WARNING] BPNode has no children.");
      return "";
    }
    str += (lastNode == null ? "0" : lastNode.id());

    return str;
  }

  // private non-static fields

  // unique identifier of this B+ tree node
  private final int id;
  // node degree of this B+ tree node
  private final int degree;
  // list of keys stored in this B+ tree node
  private List<Key> keys = null;
  // list of children stored in this B+ tree node
  private List<BPNode<Key>> children = null;

  // private static fields

  // global identifier that is increment whenever a new B+ tree node is created
  private static int globalNodeId = 0;
}
 
degree() ist also der Getter für die Variable final int degree. Beide deiner Klassen haben so eine Variable.

Die Methode key:
Java:
    public Key key(final int index) {
        return keys.get(index);
    }
Im Javadoc steht:
Code:
@throws IndexOutOfBoundsException if the index is out of range (index < 0 || index > size())
 
Ja schon aber wie könnte das jetzt aussehen? Ohne das ich eine IndexOutOfBounce bekomme? degree wird mir in dem Fall nicht viel helfen, da die letzten 2 Objekte weniger keys haben und das von input zu input variiert.
 
Klaus ich hab das schon hinbekommen. Danke für deine Antwort. Ich hätte aber noch eine andere Frage und zwar was ich mit children im Konstruktor machen soll? Die Blätter die ich in leaves speichere sind doch auch gleichzeitig children? Versteh das nicht!

LG
 

Zurück
Oben