Archive

Archive for the ‘General Programming’ Category

Remove Items While Iterating List In Java

September 27th, 2013 No comments

Edit: Some (better) alternatives here and here

Edit 2: @kattehus was awesome enough to compare the three methods. 1) my graveyard method, 2) Joe’s iterator method, and 3) Kattehus’ standard for-loop method. Go with the standard for-loop. I’ll leave the rest of my post so others can see one method of doing so, though it’s not the best method.

1
2
3
4
5
6
for (int i = items.size()-1; i >= 0; i--) {
	SomeItem item = items.get(i);
	if (item.value < 25) {
		items.remove(i);
	}
}

End of edit 2.

So you have a list of something and you want to remove some of those things from the list. So you loop through them, check to see if the item should be removed, and you remove it from the list.

*CRASH*

What happened? You likely ended up with the following stack trace.

java.util.ConcurrentModificationException
 at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
 at java.util.ArrayList$Itr.next(ArrayList.java:791)
 at RemoveFromListExample.thisWillNotWork(RemoveFromListExample.java:36)
 at RemoveFromListExample.<init>(RemoveFromListExample.java:13)
 at RemoveFromListExample.main(RemoveFromListExample.java:79)

Oops. So what went wrong? As far as Java sees it, it was happily looping through the list of items, knowing exactly how many items were in the list, when suddenly the list size changed. Java didn’t like that and so it put an end to the loop.

But you still need to remove those things from that list. What do you do? Build a second list!

I like to call the second list the “graveyard”. Basically, loop through the list and when you find something you want removed from the list just add it to the graveyard. Outside the loop just tell the first list to remove all items found in the second list. Like this:

1
2
3
4
5
6
7
8
9
public void thisOneWorks(List<SomeItem> items) {
	List<SomeItem> graveyard = new ArrayList<SomeItem>();
	for (SomeItem item : items) {
		if (item.value < discardBelowValue) {
			graveyard.add(item);
		}
	}
	items.removeAll(graveyard);
}

Below is the full source code for an example of what does and does not work, followed by the output of the program. Give it a try to see for yourself. It’s not limited to ArrayList, either. It also works with LinkedList and I presume whatever else you find in Collections.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import java.util.ArrayList;
import java.util.List;
 
public class RemoveFromListExample {
 
	protected int discardBelowValue;
 
	public RemoveFromListExample(int discardBelowValue) {
 
		this.discardBelowValue = discardBelowValue;
 
		try {
			thisWillNotWork(getList());
		} catch (Exception e) {
			e.printStackTrace();
		}
 
		thisOneWorks(getList());
	}
 
	public List<SomeItem> getList() {
		List<SomeItem> items = new ArrayList<SomeItem>();
 
		items.add(new SomeItem("Penny", 1));
		items.add(new SomeItem("Nickle", 5));
		items.add(new SomeItem("Dime", 10));
		items.add(new SomeItem("Quarter", 25));
		items.add(new SomeItem("Dollar", 100));
 
		return items;
	}
 
	public void thisWillNotWork(List<SomeItem> items) {
		printList(items);
		System.out.println("Try to delete while iterating...");
		for (SomeItem item : items) {
			if (item.value < discardBelowValue) {
				items.remove(item);
			}
		}
		printList(items);
	}
 
	public void thisOneWorks(List<SomeItem> items) {
		printList(items);
		System.out.println("Delete after iterating...");
		List<SomeItem> graveyard = new ArrayList<SomeItem>();
		for (SomeItem item : items) {
			if (item.value < discardBelowValue) {
				graveyard.add(item);
			}
		}
		items.removeAll(graveyard);
		printList(items);
	}
 
	public void printList(List<SomeItem> items) {
 
		System.out.println("Items in list");
		for (SomeItem item : items) {
			System.out.println(" * " + item.name + " (" + item.value + ")");
		}
	}
 
	private class SomeItem {
 
		protected String name;
		protected int value;
 
		public SomeItem(String name, int value) {
			this.name = name;
			this.value = value;
		}
 
	}
 
	public static void main(String[] args) {
		int discardBelowValue = 25;
		System.out.println("Discard below " + discardBelowValue + " cents");
		new RemoveFromListExample(discardBelowValue);
	}
 
}

Output:

Discard below 25 cents
Items in list
 * Penny (1)
 * Nickle (5)
 * Dime (10)
 * Quarter (25)
 * Dollar (100)
Try to delete while iterating...
java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
	at java.util.ArrayList$Itr.next(ArrayList.java:791)
	at RemoveFromListExample.thisWillNotWork(RemoveFromListExample.java:36)
	at RemoveFromListExample.(RemoveFromListExample.java:13)
	at RemoveFromListExample.main(RemoveFromListExample.java:79)
Items in list
 * Penny (1)
 * Nickle (5)
 * Dime (10)
 * Quarter (25)
 * Dollar (100)
Delete after iterating...
Items in list
 * Quarter (25)
 * Dollar (100)

PHP, curl and SSL23_GET_SERVER_HELLO

June 26th, 2013 No comments

Using the following curl block I was getting an unexpected response from the server.

1
2
3
4
5
6
7
$ch = curl_init($post_url);
curl_setopt( $ch, CURLOPT_POST, 1 );
curl_setopt( $ch, CURLOPT_POSTFIELDS, "orderXML=".$xmlRequest );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $ch, CURLOPT_TIMEOUT, 3000 );
curl_setopt( $ch, CURLOPT_VERBOSE, 1 );
$xmlResponse = curl_exec( $ch );

Pretty simple call. It’s attempting to communicate with an url over https which is where the problem lies. Here is the response I was receiving.

1
2
Curl error number: 35
Curl error: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

Simple call. Confusing problem. Simple solution. Add the following line before the curl_exec.

1
curl_setopt($ch, CURLOPT_SSLVERSION, 1);

Checking the documentation, it says this: CURLOPT_SSLVERSION - The SSL version (2 or 3) to use. By default PHP will try to determine this itself, although in some cases this must be set manually.

I tried setting the value to 2 but it didn’t work.

1
2
Curl error number: 4
Curl error: OpenSSL was built without SSLv2 support

And setting it to 3 didn’t either.

1
2
Curl error number: 35
Curl error: error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number

I wish I could tell you why setting it to 1 worked for me, but I don’t understand it. It just works for me where the documented values do not.

Categories: General Programming Tags: , , ,

Rise of the Video Game Zinesters

May 10th, 2012 No comments

I’ve been reading Anna Anthropy‘s Rise of the Videogame Zinesters
and I just came across what (to me) may be the most important message in the entire book.

Perfection isn't a useful goal; if anything, it keeps amateurs
from getting their feet wet and authors from finishing their works.
- Anna Anthropy. Rise of the Video Game Zinesters. Page 125. 2012 ed.

I cannot agree more. When I met my wife and she was getting to know me, I told her “I make games”. That wasn’t entirely true. What I should have said was “I try to make games” because my struggle for perfection constantly got in the way.

I thought there was one right way to make games, and because I didn’t know the way that I should not even try. I abandoned every game I tried to make.

It wasn’t until the last few years that I finally understood that there is no one right way to make games. That the best way to make games is just do it. Give up on perfection. Expect to make mistakes. Use bubblegum and duct tape to piece your game together and cover it up in attractive gift wrap.

People don’t see your engine (the source of my anxiety, the fear that my coding abilities would be criticised). They only see your game. Don’t try to be perfect, just make something to the best of your ability. You’ll surprise yourself.

Serialize and Deserialize series of strings

July 15th, 2011 1 comment

Just a quick example of serializing and deserializing a series of strings.

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

public class GEncode {

	String serialize(List strings) throws UnsupportedEncodingException {
		String serialized = "";
		for (String s : strings) {
			serialized += URLEncoder.encode(s, "UTF-8") + "&";
		}
		return serialized;
	}

	@SuppressWarnings("deprecation")
	List deserialize(String serialized) {
		String[] strings = serialized.split("&");
		for (int i = 0; i < strings.length; i++) {
			strings[i] = URLDecoder.decode(strings[i]);
		}
		List list = Arrays.asList(strings);
		return list;
	}

	public static void main(String[] args) throws UnsupportedEncodingException {
		List strings = new LinkedList();
		strings.add("Old & New");
		strings.add("Once upon a time!");
		strings.add("Yes, there is a monster in the closet");
		strings.add("Another string? Why, I don't mind if I do!");
		strings.add("She said \"Yes\"");

		for (String s : strings) {
			System.out.println (s);
		}

		GEncode g = new GEncode();
		String s = g.serialize(strings);

		System.out.println ("\nSerialized:\n" + s + "\n\nDeserialized:");

		List newStrings = g.deserialize(s);

		int i = 1;
		for (String ns : newStrings) {
			System.out.println (i + ": " + ns);
			i++;
		}
	}
}

Output:

Old & New
Once upon a time!
Yes, there is a monster in the closet
Another string? Why, I don't mind if I do!
She said "Yes"

Serialized:
Old+%26+New&Once+upon+a+time%21&Yes%2C+there+is+a+monster+in+the+closet&Another+string%3F+Why%2C+I+don%27t+mind+if+I+do%21&She+said+%22Yes%22&

Deserialized:
1: Old & New
2: Once upon a time!
3: Yes, there is a monster in the closet
4: Another string? Why, I don't mind if I do!
5: She said "Yes"
Categories: General Programming Tags:

Points and Line of Sight

April 18th, 2011 No comments

A very minor update, barely worth mention.

You’ll notice the entire wall segment is enclosed in the radius around the ‘player’, that yellow circle at the center. The significance here is that the top-left point of the wall segment isn’t included in the list of accessible nodes! Why not? Because, the player can’t see that node (it’s on the other side of the wall segment). Another good thing in the image above, the yellow dot is flush with the two red nodes meaning it has the same x-axis as the node to its left and same y-axis as the node above.

It’s all theory, but I believe I’m close to achieving my goal. A little recursion to jump from one point to every other point in its line of sight, adding together all the places that the orange ‘light’ can shine on, and I should finally have my map of accessible areas. Remember, it’s the idea of having a string anchored to a location, and then mapping out only the locations that the tethered string can reach.

It’ll all become clearer when I get it working. You’ll see.

Categories: Game Dev, General Programming Tags: , ,