How do I see common Items between 2 array of Objects. My intersect is not returning anything. The object is created from a Linq to SQL class.
In Java atleat, unless you override the .equals() operator, it will test for object equality (essentially using ==). That might be why the intersection is emtpy.
Did you override the Equals method?
You will need to override the object's Equals method. You can find some guidelines at Microsoft's web site.
I've provided a sample below:
public override bool Equals(System.Object obj)
{
if (obj != null && obj is MyClass)
{
MyClass obj2 = (MyClass)obj;
return (obj2.ID == this.ID);
}
}
If you do not override this method, any kind of sort/intersect/comparison will compare the objects based on their reference; so, if two objects refer to the same spot in memory, they are considered "equal."
You will have to sort them, of course.
Related
I am testing a method which should return an object of type Card. Something like:
#Test
public void testPrepareCardData() {
Card card = service.prepareData(ID);
After that I want to assert that all of the attributes of card have not been set. Let's say the method returned empty object.
One way to do it (pretty naive) is to check every attribute, like:
assertNull(card.getId());
assertNull(card.getCardNumber());
etc.
But there is many attributes and it would take some time.
Is there any sophisticated solution to that ?
You can use Reflection to perform that
Method[] methods = card.getClass().getDeclaredMethods();
for (Method method : methods) {
if (method.getName().contains("get")) {
method.setAccessible(true);
// Act & Assert
assertNull(method.invoke(card));
}
}
More information: Reflection Oracle doc
Does ActionScript have any way of handling a strongly typed list with multiple base types?
I am actually looking for something such as a Vector<T,T> ?
Is it possible?
Or is the only way of doing it is creating my own class which accepts lets say a String and Number in the constructor and create a Vector<T> out of that class?
No, not by standard. If the items are not one of the primative types you can build a Vector of interfaces, or super classes. For example, a vector of DisplayObjects that contain a mixture of MovieClips and Sprites (which both inherit from the DisplayObject).
For example:
var v:Vector.<DisplayObject> = new <DisplayObject>[
new MovieClip(),
new Sprite(),
new MovieClip()
];
trace(v[0].alpha); // outputs 1
trace(v[0].currentFrame); // error - not a DisplayObject property
In this case the vectors item will only expose the properties and methods of itself that stem from the Vectors type. But this is exactly the reason you should use vectors, it ensures the items type you are handling.
I don't know your specific case or goal, but I would consider why you need a mixed type within a vector. Your alternative option, as you stated, would be to create a wrapper class. The example below is far from complete but a starting point.
class Wrapper {
public var _value:*; // should be private with get/set's
public function Wrapper(value:*) {
if(value is String || value is Number) {
_value = value;
}
}
}
You can't do that, so I would go with your suggestion, which is to create a special class containing two properties (say Number, String) and create a Vector of that.
I am creating a method that accepts a IOBJECT parameter. there is multiple class that implement this interface. I need to figure out which type IOBJECT is. how would i go about doing that
You can use typeof, instanceof, or the 'is' operator
It's not ideal, but you can use the "is" operator. Throw it into a switch of if else statment to figure things out.
if(obj is ClassA) {
//sweetness
} else if (obj is ClassB) {
//awesomeness
}
typeof will not work, as suggested in the other reply. It will likely return "object" in all cases. instanceof will work though.
You can do getQualifiedClassName() to get the class name of the object. You can also use describeType() which gives you a more complete description of all the methods and properties of the object.
There is information about both here:
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/utils/package.html
It doesn't sound like an ideal situation though. You may want to do something where you can standardize the way you handle all items. For example:
public interface IObject {
function doSomething():void;
}
Then...
function myMethod(obj:IObject):void {
obj.doSomething();
}
I've been spending some of my spare time working a set of collections for ActionScript 3 but I've hit a pretty serious roadblock thanks for the way ActionScript 3 handles equality checks inside Dictionary Objects.
When you compare a key in a dictionary, ActionScript uses the === operator to perform the comparison, this has a bit of a nasty side effect whereby only references to the same instance will resolve true and not objects of equality. Here's what I mean:
const jonny1 : Person = new Person("jonny", 26);
const jonny2 : Person = new Person("jonny", 26);
const table : Dictionary = new Dictionary();
table[jonny1] = "That's me";
trace(table[jonny1]) // traces: "That's me"
trace(table[jonny2]) // traces: undefined.
The way I am attempting to combat this is to provide an Equalizer interface which looks like this:
public interface Equalizer
{
function equals(object : Object) : Boolean;
}
This allows to to perform an instanceOf-esq. check whenever I need to perform an equality operation inside my collections (falling back on the === operator when the object doesn't implement Equalizer); however, this doesn't get around the fact that my underlying datastructure (the Dictionary Object) has no knowledge of this.
The way I am currently working around the issue is by iterating through all the keys in the dictionary and performing the equality check whenever I perform a containsKey() or get() operation - however, this pretty much defeats the entire point of a hashmap (cheap lookup operations).
If I am unable to continue using a Dictionary instance as the backing for map, how would I go about creating the hashes for unique object instances passed in as keys so I can still maintain equality?
How about you compute a hash code for your objects when you insert them, and then look them up by the hash code in your backing dictionary? The hashcode should compare === just fine. Of course, that would require you to have a Hashable interface for your object types instead of your Equalizer interface, so it isn't much less work than you are already doing, but you do get the cheap lookups.
How about rather doing this:
public interface Hashable {
function hash():String;
}
personally, I ask myself, why you want to do this ... hashing objects to obtain keys makes little sense if they are mutable ...
also, you might consider using a different approach, as for example this factory:
package {
public class Person {
/**
* don't use this!
* #private
*/
public function Person(name:String, age:int) {
if (!instantiationAllowed)
throw new Error("use Person.getPerson instead of constructor");
//...
}
private static var instantiationAllowed:Boolean = false;
private static var map:Object = {};
private static function create(name:String, age:int):Person {
instantiationAllowed = true;
var ret:Person = new Person(name, age);
instantiationAllowed = false;
}
public static function getPerson(name:String, age:int):Person {
var ageMap:Array = map[name];
if (ageMap == null) {
map[name] = ageMap = [];
return ageMap[age] = Person.create(name, age);
}
if (ageMap.hasOwnProperty(age))
return ageMap[age];
return ageMap[age] = Person.create(name, age);
}
}
}
it ensures, there's only one person with a given name and age (if that makes any sense) ...
Old thread I know, but still worth posting.
const jonny1 : Person = new Person("jonny", 26); const jonny2 : Person = new Person("jonny", 26);
is creating two completely different objects that will not compare using ==, guess I don't see why it's any more of a road block because of as3
The problem with AS3/JavaScript/EcmaScript is not that they create two different, equivalent objects.
The problem is that they cannot equate those two equivalent objects--only identity works, since there is no equals or hashCode methods that can be overriden with class-specific comparison logic.
For Map implementations such as dynamic Object or Dictionary, this means that you have to either use Strings or references as keys: you cannot recover objects from a map using different but equivalent objects.
To work around that problem, people either resort to strict toString implementations (for Object maps) which is undesirable, or to instance control for Dictionaries, as in #back2dos example, which introduces different problems (Also, note that #back2dos solution does not really guarantee unique Person instances since there is a time window during which asynchronous threads will be allowed to instantiate new Persons).
#A.Levy's solution is good except that in general, hashCodes are not strictly required to issue unique values (they are meant to map entries to buckets allowing for fast lookups, wherein fine-grained differentiation is done through equals method).
You need both a hashCode and an equals method, e.g.
public interface IEquable
{
function equals(object : Object) : Boolean;
function hash():String;
}
In any programming language,
const jonny1 : Person = new Person("jonny", 26);
const jonny2 : Person = new Person("jonny", 26);
is creating two completely different objects that will not compare using ==, guess I don't see why it's any more of a road block because of as3
Actionscript 3.0 (and I assume Javascript and ECMAScript in general) lacks pass-by-reference for native types like ints. As a result I'm finding getting values back from a function really clunky. What's the normal pattern to work around this?
For example, is there a clean way to implement swap( intA, intB ) in Actionscript?
I Believe the best you can do is pass a container object as an argument to a function and change the values of some properties in that object:
function swapAB(aValuesContainer:Object):void
{
if (!(aValuesContainer.hasOwnProperty("a") && aValuesContainer.hasOwnProperty("b")))
throw new ArgumentError("aValuesContainer must have properties a and b");
var tempValue:int = aValuesContainer["a"];
aValuesContainer["a"] = aValuesContainer["b"];
aValuesContainer["b"] = tempValue;
}
var ints:Object = {a:13, b:25};
swapAB(ints);
I suppose an alternative would be somewhere defining this sort of thing ...
public class Reference {
public var value:*;
}
Then use functions that take some number of Reference arguments to act as "pointers" if you're really just looking for "out" parameters and either initialize them on the way in or not and your swap would become:
function swap(Reference a, Reference b) {
var tmp:* = a.value;
a.value = b.value;
b.value = tmp;
}
And you could always go nuts and define specific IntReference, StringReference, etc.
This is nitpicking, but int, String, Number and the others are passed by reference, it's just that they are immutable. Of course, the effect is the same as if they were passed by value.
You could also use a wrapper instead of int:
public class Integer
{
public var value:int;
public function Integer(value:int)
{
this.value = value;
}
}
Of course, this would be more useful if you could use operator overloading...
Just look at some Java code. Java has had the convention that reference types are passed by reference and primitive types are passed by value since it's inception. It's a very good model in many ways.
But talking about swap, the best and easiest way to do a swap in Java/AS3 is with the following three lines:
var temp:int = array[i];
array[j] = array[i];
array[i] = temp;
Theres not really any reason to use a function to do a simple swap, when you can do it faster with just 3 lines.
It is annoying. But if you use different idioms than in e.g. C#, you can get reasonable-quality results. If you need to pass a lot of parameters back and forth, pass in an object filled with the needed data, and change the object's parameters when you return. The Object class is for just this sort of thing.
If you just need to return a bunch of data, return an Object. This is more in keeping with the ECMAScript style than pass-by-ref semantics.
Destructuring assignment (e.g. [a,b] = [b,a]) isn't defined in the ECMA-262 3 specification, and it's not implemented in JavaScript 1.5, which is the version equivalent to the JScript implementation in IE. I've seen this syntax in the AS4 specifications preview though, and I believe it's part of JavaScript 1.7.
If ActionScript works like Javascript,
[a,b] = [b,a]