1

元のコードでは、ノードをツリーに追加しています。私の目標は、ツリーに追加した最後のノードに何らかの方法でアクセスできるようにすることです(私のアイデアは、最後のオブジェクト(元の例ではノード)を指す別のオブジェクトを作成することでした)。

public class RandomSubClass 
{
    int firstNum;
}    

import java.util.LinkedList;

public class RandomClass 
{
    LinkedList<RandomSubClass> myListOfObjects = new LinkedList<RandomSubClass>();

    void addItem(int firstNum, RandomSubClass toBeReturned)
    {       
        RandomSubClass o1 = new RandomSubClass();
        o1.firstNum = firstNum;
        myListOfObjects.add(o1);

        // Here I was thinking that 'toBeReturned' will get same address as
        // 'o1', and by changing 'toBeReturned' (in main), values in 'o1' change
        //
        toBeReturned = o1;

        // This following commented code worked, 
        // but I can't use it in my original code.
        //
        // The reason I can't use it is because when I add a node to a tree, 
        // I start at the root and trace the new node's way to a new leaf, 
        // which makes it hard to do (simply) that.
        //
        //toBeReturned.firstNum = firstNum;
        //myListOfObjects.add(toBeReturned);
    }   
}

public class Main 
{
    public static void main(String[] args) 
    {
        RandomClass myList = new RandomClass();

        RandomSubClass r1 = new RandomSubClass();
        RandomSubClass r2 = new RandomSubClass();

        myList.addItem(1, r1);
        myList.addItem(2, r2);

        // I would like to do that, and see changes in the node in 'myList'
        //  
        r1.firstNum = 10;
        r2.firstNum = 20;
    }
}

ツリーにノードを追加した後、ノードについて何かをチェックしたいのですが、それが何らかの条件を満たす場合は、そのノードのフラグを変更したいと思います。

(ルートから開始して)ノードを再度トレースすることはできますが、ある時点でツリーが巨大になる可能性があり、時間がかかります。したがって、追加するときにそのノードのアドレスを取得し、状態を確認した後、そのノード(最後に追加された)のフラグが変更されることを知って、そのアドレスのフラグを変更できます。

4

3 に答える 3

2

はい、あなたはこれを行うことができます。私はあなたに許可を与えます。:-)しかし、Javaオブジェクトは参照ではなく値で渡されるため、サンプルコードは機能しません。つまり、オブジェクトを関数に渡すときに、そのオブジェクトを再割り当てしても、呼び出し元には影響しません。例えば:

void caller()
{
  String s1="Hello";
  updateString(s1);
  System.out.println(s1);
}
void updateString(String s1)
{
  s1="Goodbye";
}

この関数の出力は「さようなら」ではなく「こんにちは」です。updateString関数内の割り当ては、呼び出し元から渡された値を変更しません。

あなたがやりたいことをするために(少なくとも)3つの方法があります。

方法1:最も簡単な方法は、パラメーターを更新するのではなく、新しいオブジェクトを返すことです。

SomeObject addItem(int firstnum)
{
  SomeObject o1=new SomeObject();
  o1.firstnum=firstnum;
  objectList.add(o1);
  return o1;
}
...
void callingFunction()
{
  SomeObject newObject=addItem(1);
  newObject.secondnum=2;
  ... etc ...
}

私はこのメソッドを好みます。他の戻り値は必要ありません。クリーンでシンプルです。

方法2:グローバル変数を作成し、そこにオブジェクトのハンドルを格納します。しかし、グローバルは一般的に悪いので、この方法は悪いです。私はあなたにそれをしないように言うためにそれについて言及するだけです。

方法3:オブジェクトへの参照を保持するラッパーを作成します。次に、ラッパーを「add」関数に渡します。この関数は、クラス内の値を更新できます。

class SomeObjectWrapper
{
  public SomeObject someObject;
}
...
void addItem(int firstnum, SomeObjectWrapper sow)
{
  SomeObject o1=new SomeObject();
  o1.firstnum=firstnum;
  objectList.add(o1);
  sow.someobject=o1;
}
...
void callingFunction()
{
  SomeObjectWrapper sow=new SomeObjectWrapper();
  SomeObject newObject=addItem(1, sow);
  sow.someObject.secondnum=2;
  ... whatever ...
}
于 2012-04-26T17:59:16.663 に答える
1

戻り値でそれを行うのはどうですか?

RandomSubClass addItem(int firstNum)
{       
    RandomSubClass o1 = new RandomSubClass();
    o1.firstNum = firstNum;
    myListOfObjects.add(o1);

    // Here I was thinking that 'toBeReturned' will get same address as
    // 'o1', and by changing 'toBeReturned' (in main), values in 'o1' change
    //
    ....
    return o1
}
于 2012-04-26T17:50:03.233 に答える
0

Javaでは、すべてのオブジェクトがアドレスによってパラメータを介して返される/渡されます。プリミティブ型をアドレスで渡す場合は、プリミティブ型(int、float、double ...)のみが値で渡されます。intの代わりに整数-doubleの代わりにDouble-Floatの代わりにFloat-ect。 ..

于 2012-04-26T17:55:07.977 に答える