I'm writing a method that adds a new Node to the back of a linked list:
public void add(string title, string director, int year, double cost)
{
Node newNode = new Node();
newNode.disc = new BluRayDisc(title, director, year, cost);
Node holder = new Node();
holder = first;
while (holder.next != null) //object reference error
{
holder = holder.next;
}
holder.next = newNode;
}
but am getting a "System.NullReferenceException: 'Object reference not set to an instance of an object.'" error thrown.
The 'first' node is initialized to null so I'm assuming that's where my problem comes from.
This is my first linked list, and this follows the example of an addToBack method I was given exactly. Does anyone have some insight on this problem?
A few issues:
first can be null, which is the case when you start with an empty linked list, and in that case first.next is an invalid reference.
About: Node holder = new Node();. It is not necessary to create a new node here, with new Node(), since in the next statement, you are throwing away that node, by doing holder = first;
Here is the correction:
public void add(string title, string director, int year, double cost)
{
Node newNode = new Node();
newNode.disc = new BluRayDisc(title, director, year, cost);
if (first == null) {
first = newNode;
return;
}
holder = first;
while (holder.next != null) //object reference error
{
holder = holder.next;
}
holder.next = newNode;
}
As you mentioned, the problem is that the variable "first" is initialized to null. It should be set the to the first node of the linked list you are constructing.
Related
I am trying to reverse linked list using java and written below code.
class Solution {
public ListNode reverseList(ListNode head) {
ListNode cur=head,prev=null,newHead=null;
while(cur!=null)
{
newHead=cur;
newHead.next=prev;
prev=newHead;
System.out.println(1);
cur=cur.next;
}
return newHead;
}
}
I am not understanding why the loop is executed only once here. Am i doing something wrong?
This happens because you have altered cur.next with the assignment newHead.next=prev;, making it null. Realise that newHead references the same object as cur at that moment.
You should save the original value of cur.next before this change happens:
ListNode cur = head, prev = null, newHead = null, next;
while (cur != null)
{
newHead = cur;
next = cur.next; // <--- save original value of `cur.next`
newHead.next = prev;
prev = newHead;
cur = next; // <--- use that original value here
}
I'm trying to create a grammar, using implicit declarations. After reading the a forum entry (http://www.eclipse.org/forums/index.php?t=msg&S=2e4a29d7fff0322e71b35e3a3aa63e3f&th=198813&goto=634090#msg_634090) I wrote my own LinkingService:
public class OntMLLinkingService extends DefaultLinkingService {
private final Map<Rule, Resource> implicitVariables = new HashMap<>();
public List<EObject> getLinkedObjects(EObject context, EReference ref, INode node) throws IllegalNodeException {
List<EObject> linking = super.getLinkedObjects(context, ref, node);
if (!linking.isEmpty())
return linking;
if (context instanceof VariableReference && ref.equals(OntMLPackage.eINSTANCE.getVariableReference_Variable())) {
// Find the rule, the references is used in
EObject container = context.eContainer();
while (!(container instanceof Rule))
container = container.eContainer();
Rule rule = (Rule) container;
// Check, if a resource was already created for the rule
Resource res = implicitVariables.get(rule);
if (res == null) {
// Create and register new resource
res =
rule.eResource().getResourceSet()
.createResource(URI.createURI("http://wwwcs.vs.hs-rm.de/OntML/Variable/" + UUID.randomUUID()));
implicitVariables.put(rule, res);
}
// Get the cross ref string
final String crossRefString = getCrossRefNodeAsString(node);
if (crossRefString != null && !crossRefString.equals("")) {
// Search for the variable in the resource
Optional<Variable> existingVar =
res.getContents().stream().map(eobj -> (Variable) eobj).filter(var -> var.getName().equals(crossRefString))
.findAny();
if (!existingVar.isPresent()) {
// Create and register new variable, if the variable does not exist yet
Variable newvar = OntMLFactory.eINSTANCE.createVariable();
newvar.setName(crossRefString);
res.getContents().add(newvar);
}
}
// Add all contents of the resource to the linked objects
linking.addAll(res.getContents());
}
return linking;
}
}
I've debugged the "getLinkedObjects" method and everything seems to work fine, but my editor won't show errors anymore, even though I write invalid code and my compiler gets a null pointer, when invoking the "getName" method of any "Variable". I think it's a problem with the LazyLinker and EMF proxies.
I had a method which fetched records from an sqlite database but after a while i changed it a little and made a secondary method for fetching specific records with user entered information.
I don't know why but my original method is returning null now.
CardDbAdapter:
public CarddbAdapter open2() throws SQLException {
String myPath = DB_PATH + DB_NAME;
myDatabaseR = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
myDatabaseW = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
return this;
}
public void MyDatabaseClose() {
myDatabaseW.close();
myDatabaseR.close();
}
public ArrayList<String> getAllCardNames() {
ArrayList<String> returnedAllCardNames;
ArrayList<String> NoResults;
ArrayList<String> NoResults2;
NoResults = new ArrayList<String>();
NoResults.add("cursor is null");
NoResults2 = new ArrayList<String>();
NoResults2.add("No similar cards found.");
returnedAllCardNames = new ArrayList<String>();
/*String sqlquery_cardNames = "SELECT " + KEY_CARDNAME
+ " FROM cards WHERE card_name like '%" + passedName
+ "%' ORDER BY card_name ASC";*/
//String sqlquery_cardNames;
String sqlquery_cardNames = "SELECT DISTINCT card_name FROM cards";
Cursor c_cardNames;
c_cardNames = myDatabaseW.rawQuery(sqlquery_cardNames, null);
c_cardNames.moveToFirst();
if (c_cardNames != null) {
do {
if (c_cardNames.getCount() > 0) {
String returnedName = c_cardNames.getString(c_cardNames
.getColumnIndex(KEY_CARDNAME));
returnedAllCardNames.add(returnedName);
} else {
return NoResults2;
}
} while (c_cardNames.moveToNext());
}
return NoResults;
}
How i am using it:
CarddbAdapter yugiohDB = new CarddbAdapter(this);
yugiohDB.open2();
search_results = (ListView) findViewById(R.id.lvSearchResults);
search_results.setOnItemClickListener(this);
ArrayList<String> returnedCards_list1 = new ArrayList<String>();
returnedCards_list1.addAll(yugiohDB.getAllCardNames());
listAdapter = new ArrayAdapter<String>(SearchMode_Simple.this,
android.R.layout.simple_list_item_1, returnedCards_list1);
search_results.setAdapter(listAdapter);
yugiohDB.MyDatabaseClose();
Any help would be appreciated.
If you would like to see what this is actually supposed to do then download my app called Yugioh Library + Tools. Click the Search Library button from the main menu and then the button Simple Search. It should be displaying a list of cards from the database.
The reason i was changing it is because i'm setting up Spinners so users can choose different trading card sets to choose some which would then list all the cards from that specific set.
Fixed. I forgot to return the string array "returnedAllCardNames" which was holding the names of all process card records after the do while loop.
Im using vaadin's TreeTable and im trying to add tooltips for my rows. This is how they say it should be done but the propertyId is always null so i cant get the correct column? And yes i'v run this in eclipse debugger aswell =)
Code related to this part:
private void init() {
setDataSource();
addGeneratedColumn("title", new TitleColumnGenerator());
addGeneratedColumn("description", new DescriptionGenerator());
setColumnExpandRatios();
setItemDescriptionGenerator(new TooltipGenerator());
}
protected class TooltipGenerator implements ItemDescriptionGenerator{
private static final long serialVersionUID = 1L;
#Override
public String generateDescription(Component source, Object itemId, Object propertyId) {
TaskRow taskRow = (TaskRow)itemId;
if("description".equals(propertyId)){
return taskRow.getDescription();
}else if("title".equals(propertyId)){
return taskRow.getTitle();
}else if("category".equals(propertyId)){
return taskRow.getCategory().toString();
}else if("operation".equals(propertyId)){
return taskRow.getOperation().toString();
}else if("resourcePointer".equals(propertyId)){
return taskRow.getResourcePointer();
}else if("taskState".equals(propertyId)){
return taskRow.getTaskState().toString();
}
return null;
}
}
I have passed the source object as the itemId when adding an item to the tree.
Node node = ...;
Item item = tree.addItem(node);
this uses the object "node" as the id. Which then allows me to cast itemId as an instance of Node in the generateDescription method.
public String generateDescription(Component source, Object itemId, Object propertyId) {
if (itemId instanceof Node) {
Node node = (Node) itemId;
...
Maybe not the best solution, but it Works for me. Then again, I am adding items directly to the tree rather than using a DataContainer.
I want to create a method which can takes the properties I possibly may update and leaving those not interested untouched.
Here is what I did:
public static void updateTable(int id, string field1, string field2, string field3){
using(var context = new Entities()){
var obj = context.Table.Where(x=>x.id == id).FirstOrDefault();
if(obj != null){
obj.field1 = field1;
...
obj.SaveChanges();
}
}
}
But in this pattern, I need to pass all 4 parameters into the method even I just want to update only one field. Is there any generic solution to update only the fields I passed in?
I came up something like this:
public static void updateTable(int id, object data_json){
using(var context = new Entities()){
var obj = context.Table.Where(x=>x.id == id).FirstOrDefault();
if(obj != null){
if(data_json['field1']!=null) //something like this
obj.field1 = data_json['field1'];
...
obj.SaveChanges();
}
}
}
But this can't handle the case that I do want to set a field to be null. Or is there any better solution?
If you don't care about updating relationships, you can use ApplyCurrentValues, which only updates the scalar properties.
E.g:
public static void updateTable(int id, object data_json){
using(var context = new Entities()) {
var obj = context.Table.Where(x=>x.id == id).FirstOrDefault();
context.ApplyCurrentValues("Table", data_json);
}
}
It assumes an entity with the same key is already attached in the graph. In this case, the query for var obj will ensure the object is in the graph, then it's contents are overridden with the scalar properties on the supplied object.
You might need an explicit cast on data_json to ensure it is of the same type contained in the entity set.
Using an ExpandoObject would allow you to send in only the properties you want to set, and would allow you to specify null values as well.
For example:
public static void updateTable(int id, dynamic data){
using(var context = new Entities()){
var obj = context.Table.Where(x=>x.id == id).FirstOrDefault();
if(obj != null){
if (((IDictionary<string, object>)data).ContainsKey("field1"))
obj.field1 = data.field1;
...
obj.SaveChanges();
}
}
}
and you could call it like this:
dynamic data = new ExpandoObject();
data.field1 = 123;
data.field2 = null;
data.field5 = "abc";
MyClass.updateTable(1, data);
Everything can be solved with a moment of reflection. This function solves the problem:
public void UpdateTable(int id, object values)
{
using (var entities = new MyEntities())
{
var valuesType = values.GetType();
var element = entities.MyTable.Where(t => t.ID == id).First();
//We are iterating through all properties of updated element and checking
//if there is value provided for there properties in values parameter
foreach (var property in element.GetType().GetProperties())
{
var valuesProperty = valuesType.GetProperty(property.Name);
//If values contain this property
if (valuesProperty != null)
{
//taking value out of values parameter
var value = valuesProperty.GetValue(values, null);
//setting it in our element to update
property.SetValue(element, value, null);
}
}
entities.SaveChanges();
}
}
Usage:
UpdateTable(125, new { FieldA = 1, FieldB = "ABCD" });
You can even make this method more universal by adding generic table type parameter.