2013-11-23 4 views
3

Я много искал об объектах пропуска типа ArrayList, но я не нашел ничего полезного для решения моей проблемы. В этом есть проблема:Циркулярная ссылка на составные объекты

У меня есть класс Vertex (который реализует Parcelable), который имеет 4 атрибута: name (String), minDistance (double), предыдущий (Vertex) и ArrayList смежности (ArrayList of Edges).

У меня также есть класс Edge (который реализует Parcelable) с 3 атрибутами: от (вершина), цель (вершина) и вес (двойной).

В моей MainActivity у меня есть ArrayList из вершин (где каждый из них имеет ArrayList of Edges), и я хочу перейти к другому действию my ArrayList. В этот момент у меня есть StackOverflowError.

Класс Vertex.java

public class Vertex implements Comparable<Vertex>, Parcelable { 
    public final String name; 
    public List<Edge> adjacencies = new ArrayList<Edge>(); 
    public double minDistance = Double.POSITIVE_INFINITY; 
    public Vertex previous; 

    public Vertex(String argName) { 
     name = argName; 
    } 

    public Vertex(Parcel in) { 
     this.name = in.readString(); 
     this.minDistance=in.readDouble(); 
     Object[]aristas= in.readArray(Edge.class.getClassLoader()); 
     setAdjacencies(aristas); 
    } 

    public void addEdge(Edge e) { 
     adjacencies.add(e); 
    } 

    public String toString() { 
     return name; 
    } 

    public int compareTo(Vertex other) { 
     return Double.compare(minDistance, other.minDistance); 
    } 

    @Override 
    public int describeContents() { 
     // TODO Auto-generated method stub 
     return 0; 
    } 

    @Override 
    public void writeToParcel(Parcel dest, int flags) { 
     // TODO Auto-generated method stub 
     dest.writeString(name); 
     dest.writeDouble(minDistance);  
     Object[] edgesArray = adjacencies.toArray(); 
     dest.writeArray(edgesArray); 

    } 

    public static final Parcelable.Creator<Vertex> CREATOR = new Parcelable.Creator<Vertex>() { 
     public Vertex createFromParcel(Parcel in) { 
      return new Vertex(in); 
     } 

     public Vertex[] newArray(int size) { 
      return new Vertex[size]; 
     } 
    }; 

    public void setAdjacencies(Object[] edges) { 
     for (Object edge : edges) { 
      if (edge instanceof Edge) { 
       adjacencies.add((Edge) edge); 
      } 
     } 
    } 

} 

Класс Edge.java

public class Edge implements Parcelable { 

    private Vertex from; 
    private Vertex target; 
    private double weigth; 

    public Edge(Vertex from, Vertex target, double weight) { 
     this.target = target; 
     this.weigth = weight; 
     this.from = from; 
    } 

    public Edge(Parcel in) { 
     this.weigth=in.readDouble(); 
     this.target=(Vertex) in.readParcelable(getClass().getClassLoader()); 
     this.from=(Vertex) in.readParcelable(getClass().getClassLoader()); 
    } 

    public Vertex getTarget() { 
     return target; 
    } 

    public void setTarget(Vertex target) { 
     this.target = target; 
    } 

    public double getWeigth() { 
     return weigth; 
    } 

    public void setWeigth(double weigth) { 
     this.weigth = weigth; 
    } 

    public Vertex getFrom() { 
     return from; 
    } 

    public void setFrom(Vertex from) { 
     this.from = from; 
    } 

    @Override 
    public String toString() { 
     // TODO Auto-generated method stub 
     return getFrom().toString() + " -> " + weigth + " -> " 
       + getTarget().toString(); 
    } 

    @Override 
    public int describeContents() { 
     // TODO Auto-generated method stub 
     return 0; 
    } 

    @Override 
    public void writeToParcel(Parcel dest, int flags) { 
     // TODO Auto-generated method stub 
     dest.writeDouble(weigth); 
     dest.writeParcelable(target,flags); 
     dest.writeParcelable(from, flags); 

    } 

    public static final Parcelable.Creator<Edge> CREATOR = new Parcelable.Creator<Edge>() { 
     public Edge createFromParcel(Parcel in) { 
      return new Edge(in); 
     } 

     public Edge[] newArray(int size) { 
      return new Edge[size]; 
     } 
    }; 

} 

Я действительно ценю вашу помощь

Спасибо

Я забыл показать путь I Посылка и прием посылок:

Для отправки (Fragment.java):

i.putParcelableArrayListExtra("LIST_VERTEX", ((MainActivity)getActivity()).getListaVertex()); 

Чтобы получить (ResultActivity.java):

nodos = getIntent().getParcelableArrayListExtra("LIST_VERTEX"); 

Примечание:. ((MainActivity) getActivity()) getListaVertex() является ArrayList объекты вершинного

LogCat:

11-23 01: 52: 25,384: Е/AndroidRuntime (21939): неустранимые: Главный 11-23 01: 52: 25.384: E/AndroidRuntime (21939): java.lang.StackOverflowError 11-23 01: 52: 25.384: E/AndroidRuntime (21939): на android.os.Parcel.writeString (Parcel.java:513) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.Vertex.writeToParcel (Vertex.java:56) 11-23 01: 52: 25.384: E/AndroidRuntime (21939) : at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.EdgesList.writeToParcel (EdgesList.java:48) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.Vertex.writeToParcel (Vertex.java:58) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Par cel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.EdgesList.writeToParcel (EdgesList.java:48) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.Vertex.writeToParcel (Vertex.java:58) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.EdgesList.writeToParcel (EdgesList.java:48) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java: 1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.Vertex.writeToParcel (Vertex.java:58) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.EdgesList.writeToParcel (EdgesList. java: 48) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.Vertex.writeToParcel (Vertex.java:58) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java: 1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.EdgesList.writeToParcel (EdgesList.java:48) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.Vertex.writeToParcel (Vertex.java:58) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11 -23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.EdgesList.writeToParcel (EdgesList.java:48) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.Vertex.writeToParcel (Vertex.java:58) 11 -23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939)): at com.csacanam.dijkstra.EdgesList.writeToParcel (EdgesList.java:48) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.Vertex.writeToParcel (Vertex.java:58) 11-23 01: 52: 25.384: E/AndroidRuntime (21939)): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): на com.csacanam.dijkstra.EdgesList.writeToParcel (EdgesList.java:48)) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): на com.csacanam.dijkstra.Vertex.writeToParcel (Vertex.java:58) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcela (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.EdgesList.writeToParcel (EdgesList.java:48) 11-23 01:52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.Vertex. writeToParcel (Vertex.java:58) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.EdgesList.writeToParcel (EdgesList.java:48) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.Vertex.writeToParcel (Vertex.java:58) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.EdgesList.writeToParcel (EdgesList.java:48) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11 -23 01: 52: 25.384: E/AndroidRuntime (21939): на com.csacanam.dijkstra.Vertex.writeToParcel (Vertex.java:58) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.EdgesList.writeToParcel (EdgesList.java:48) 11 -23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01:52:25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.Vertex.writeToParcel (Vertex.java:58) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): на android.os.Parcel. writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.EdgesList.writeToParcel (EdgesList.java:48) 11-23 01:52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.Vertex. writeToParcel (Vertex.java:58) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.EdgesList.writeToParcel (EdgesList.java:48) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at и roid.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.Vertex.writeToParcel (Vertex.java:58) 11 -23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com. csacanam.dijkstra.EdgesList.writeToParcel (EdgesList.java:48) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at com.csacanam.dijkstra.Vertex.writeToParcel (Vertex.java:58) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): у android. os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): на com.csacanam.dijkstra.EdgesList.writeToParcel (EdgesL ist.java:48) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): at android.os.Parcel.writeParcelable (Parcel.java:1254) 11-23 01: 52: 25.384: E/AndroidRuntime (21939): в com.csacanam.dijkstra.Vertex.writeToParcel (Vertex

EDIT:

Это решение решить мою проблему круговой ссылки

New Edge класс:

public class Edge implements Parcelable { 

    public String PKhash; 
    private Vertex from; 
    private Vertex target; 
    private double weigth; 

    public static HashMap<String, Vertex> _parentsFrom = new HashMap<String, Vertex>(); 
    public static HashMap<String, Vertex> _parentsTarget = new HashMap<String, Vertex>(); 

    public String get_PKhash() { 
     /* Return a unique identifier of your Edge object here */ 
     return PKhash; 
    } 

    public Edge(Vertex from, Vertex target, double weight) { 
     this.target = target; 
     this.weigth = weight; 
     this.from = from; 
     this.PKhash=from.name+","+getWeigth()+","+target.name; 
    } 

    public Edge(Parcel in) { 
     this.weigth = in.readDouble(); 
     this.PKhash = in.readString(); 
     Assert.assertTrue((from = _parentsFrom.get(this.PKhash)) != null); 
     Assert.assertTrue((target = _parentsTarget.get(this.PKhash)) != null); 
    } 


    public Vertex getTarget() { 
     return target; 
    } 

    public void setTarget(Vertex target) { 
     this.target = target; 
    } 

    public double getWeigth() { 
     return weigth; 
    } 

    public void setWeigth(double weigth) { 
     this.weigth = weigth; 
    } 

    public Vertex getFrom() { 
     return from; 
    } 

    public void setFrom(Vertex from) { 
     this.from = from; 
    } 

    @Override 
    public String toString() { 
     // TODO Auto-generated method stub 
     return getFrom().toString() + " -> " + weigth + " -> " 
       + getTarget().toString(); 
    } 

    @Override 
    public int describeContents() { 
     // TODO Auto-generated method stubz 
     return 0; 
    } 

    @Override 
    public void writeToParcel(Parcel dest, int flags) { 
     // TODO Auto-generated method stub 
     dest.writeDouble(weigth); 
     this.PKhash=""; 
     this.PKhash=from.name+","+getWeigth()+","+target.name; 
     dest.writeString(PKhash); 
     _parentsFrom.put(PKhash, from); 
     _parentsTarget.put(PKhash, target); 

    } 

    public static final Parcelable.Creator<Edge> CREATOR = new Parcelable.Creator<Edge>() { 
     public Edge createFromParcel(Parcel in) { 
      return new Edge(in); 
     } 

     public Edge[] newArray(int size) { 
      return new Edge[size]; 
     } 
    }; 


} 

Новый класс вершин

public class Vertex implements Comparable<Vertex>, Parcelable { 
    public final String name; 
    public List<Edge> adjacencies = new ArrayList<Edge>(); 
    public double minDistance = Double.POSITIVE_INFINITY; 
    public Vertex previous; 

    public Vertex(String argName) { 
     name = argName; 
    } 

    public Vertex(Parcel in) { 
     this.name = in.readString(); 
     this.minDistance=in.readDouble(); 
     Object[]aristas= in.readArray(Edge.class.getClassLoader()); 
     setAdjacencies(aristas); 
    } 

    public void addEdge(Edge e) { 
     adjacencies.add(e); 
    } 

    public String toString() { 
     return name; 
    } 

    public int compareTo(Vertex other) { 
     return Double.compare(minDistance, other.minDistance); 
    } 

    @Override 
    public int describeContents() { 
     // TODO Auto-generated method stub 
     return 0; 
    } 

    @Override 
    public void writeToParcel(Parcel dest, int flags) { 
     // TODO Auto-generated method stub 
     dest.writeString(name); 
     dest.writeDouble(minDistance);  
     Object[] edgesArray = adjacencies.toArray(); 
     dest.writeArray(edgesArray); 

    } 

    public static final Parcelable.Creator<Vertex> CREATOR = new Parcelable.Creator<Vertex>() { 
     public Vertex createFromParcel(Parcel in) { 
      return new Vertex(in); 
     } 

     public Vertex[] newArray(int size) { 
      return new Vertex[size]; 
     } 
    }; 

    public void setAdjacencies(Object[] edges) { 
     for (Object edge : edges) { 
      if (edge instanceof Edge) { 
       adjacencies.add((Edge) edge); 
      } 
     } 
    } 

    @Override 
    public int hashCode() { 
     // TODO Auto-generated method stub 
     return name.hashCode(); 
    } 

} 
+1

Зачем вам нужен ArrayList, который реализует Parcelable? вместо этого вы можете напрямую добавлять объекты Parcelable в ArrayList. –

+0

Это было последнее, что я сделал, чтобы попытаться решить мою проблему. До этого у меня был только ArrayList для каждого Vertex, но когда я пытаюсь отправить ArrayList , у меня было то же исключение. –

+0

Пожалуйста, разместите logcat – Egor

ответ

1

Вам не нужно использовать Parcelable в вашем EdgeList. На самом деле, из того, что я понимаю, вам вообще не нужно EdgeList. Просто измените Vertex класс следующим образом:

public List<Edge> adjacencies = new ArrayList<Edge>(); 

public Edge(Parcel in) { 
    name = in.getString(); 
    minDistance = in.getDouble(); 
    adjancencies = in.readParcelableArray(Edge.getClass().getClassLoader()); 
} 

@Override 
public void writeToParcel(Parcel dest, int flags) { 
    dest.writeString(name); 
    dest.writeDouble(minDistance); 
    pc.writeParcelableArray((ArrayList<? extends Parcelable>) adjacencies, flags); 

} 

Я просто не уверен, что вы можете иметь Vertex членов в вашем Edge классе, потому что может создать циклическую ссылку. Попробуйте сначала протестировать его без этих участников.

EDIT:

После прочтения некоторых предложений здесь: android parcelable referencing another parcelable circular dependence, я думаю, вы можете попробовать следующее:

В вашем Edge классе, не пишите ссылку на Vertex членов в вашем writeToParcel(). Вместо этого, попробуйте следующее:

public class Edge implements Parcelable { 

    private Vertex from; 
    private Vertex target; 
    private double weigth; 

    static HashMap<Long, Vertex> _parentsFrom = new HashMap<Long, Vertex>(); 
    static HashMap<Long, Vertex> _parentsTarget = new HashMap<Long, Vertex>(); 

    public long get_PKhash() { /* Return a unique identifier of your Edge object here */ } 

    private ItemClass(Parcel in) { 
     (...) 
     assertTrue((from = _parentsFrom.remove(get_PKhash())) != null); 
     assertTrue((target = _parentsTarget.remove(get_PKhash())) != null); 
    } 

    public void writeToParcel(Parcel p, int args) { 
     (...)//Don't write to the parcel your from and target objects 
     _parentsFrom.put(this.get_PKhash, from); 
     _parentsTarget.put(this.get_PKhash, to); 
    } 
} 

Обратите внимание, что вы, по-видимому, не можете иметь циклические ссылки в Parcelable реализаций. Это вышеописанное решение является хакерским обходным решением, и оно будет работать только в том случае, если вы сможете убедиться, что каждый ваш экземпляр края уникально идентифицирован в вашем приложении.

Надеюсь, это поможет.

+0

Спасибо за ваш ответ Рикардо. Я просто изменил свой класс Vertex, и теперь смежные атрибуты - ArrayList , но это та же проблема. Я тестирую его без членов Vertex в моем классе Edge, но проблема в том, что мне нужно в другом действии оба элемента Vertex (from и target). По этой причине у меня есть исключение NullPointerException. –

+0

Это не работает, потому что мне нужен этот объект в другом действии. По этой причине мне нужно отправить их в writeToParcel и получить их в конструкторе Vertex (Parcel in) –

+0

Какие объекты вы говорите? –

Смежные вопросы