If you want to access all fields in one record as key-value pairs, you can use
accounts[i].getPopulatedFieldsAsMap()
To compare all fields between two objects, even if they are not populated, look into "Dynamic Apex" and describe operations. This code will retrieve all API names on the object:
Map<String, Schema.SObjectField> fieldsMap = Schema.SObjectType.Account.fields.getMap();
You can then iterate over the map keys like this:
for(String field : fieldsMap.keySet()){
System.debug(field + ': ' + accounts[i].get(field));
}
If you are working with classes that you cannot control and reflection is not available in Apex, you can try this approach. Serialize the objects to JSON and compare them:
public with sharing class Stack47339633{
public String name, some, other, property;
public Integer someInt;
public Date d;
}
Stack47339633 obj1 = new Stack47339633();
obj1.name = 'hello';
obj1.some = 'world';
obj1.someInt = 13;
obj1.d = System.today();
Stack47339633 obj2 = new Stack47339633();
obj2.name = 'hello';
obj2.some = 'stackoverflow';
obj2.someInt = -7;
obj2.d = System.today();
Map<String, Object> o1 = (Map<String,Object>) JSON.deserializeUntyped(JSON.serialize(obj1));
Map<String, Object> o2 = (Map<String,Object>) JSON.deserializeUntyped(JSON.serialize(obj2));
Map<String, Object> o3 = new Map<String, Object>();
for(String s : o1.keySet()){
System.debug(s + ':' + o1.get(s) + ' == ' + o2.get(s) + '?');
if(o1.get(s) == o2.get(s)){
System.debug('match!');
o3.put(s, o1.get(s));
}
}
Stack47339633 obj3 = (Stack47339633) JSON.deserialize(JSON.serialize(o3), Stack47339633.class);
System.debug('Full result: ' + obj3);
System.debug('Name : ' + obj3.name);
System.debug('someint : ' + obj3.someInt);
System.debug('d : ' + obj3.d);
While this method involves casting to JSON and back, it's effective. Serialization may fail in certain cases, but it's a viable option.
Check out these resources for more information: