The “Referencing Apex Maps and Lists” section of the Visualforce Developer’s Guide provides examples of how to reference data held in an Apex map in the controller from a Visualforce page. I haven’t found examples where the key values used have been other than strings or integers and the documentation is not explicit. But now that there is support for Non-primitive Types in Map Keys and Sets, I thought it would be worth trying a DateTime value as a map key in a page I have that heavily uses DateTime objects.
But DateTime as a map key type does not work from Visualforce:
Incorrect parameter type for subscript. Expected java.lang.Class, received DateTime
To get some sense of what does and what does not work I created the controller and page listed at the end of this post (both set to API 26.0). I found two further failing map key types.
Time as a map key type results in:
Unsupported type shared.xml.soap.Time encountered.
A custom Apex class as a map key type results in:
Map key Custom:[value=987] not found in map
i.e. value semantics are not supported (but the generally less useful reference semantics are).
I’ll create a case with Salesforce about the types that don’t work.
<apex:page controller="MapTestController">
<h1>Map Test</h1>
<br/><apex:outputText value="{!stringKeyMap[stringKey]}"/>
<br/><apex:outputText value="{!integerKeyMap[integerKey]}"/>
<br/><apex:outputText value="{!longKeyMap[longKey]}"/>
<br/><apex:outputText value="{!decimalKeyMap[decimalKey]}"/>
<br/><apex:outputText value="{!dateKeyMap[dateKey]}"/>
<br/><apex:outputText value="{!customByReferenceKeyMap[customByReferenceKey]}"/>
<!--
<br/><apex:outputText value="{!timeKeyMap[timeKey]}"/>
-->
<!--
<br/><apex:outputText value="{!dateTimeKeyMap[dateTimeKey]}"/>
-->
<!--
<br/><apex:outputText value="{!customByValueKeyMap[customByValueKey]}"/>
-->
</apex:page>
public class MapTestController {
public String stringKey {
get {
return 'key';
}
}
public Map<String, String> stringKeyMap {
get {
return new Map<String, String>{stringKey => 'string value'};
}
}
public Integer integerKey {
get {
return 1234;
}
}
public Map<Integer, String> integerKeyMap {
get {
return new Map<Integer, String>{integerKey => 'integer value'};
}
}
public Long longKey {
get {
return 1234;
}
}
public Map<Long, String> longKeyMap {
get {
return new Map<Long, String>{longKey => 'long value'};
}
}
public Decimal decimalKey {
get {
return 3.25;
}
}
public Map<Decimal, String> decimalKeyMap {
get {
return new Map<Decimal, String>{decimalKey => 'decimal value'};
}
}
public Date dateKey {
get {
return Date.newInstance(2012, 1, 1);
}
}
public Map<Date, String> dateKeyMap {
get {
return new Map<Date, String>{dateKey => 'date value'};
}
}
public Time timeKey {
get {
return Time.newInstance(8, 20, 30, 0);
}
}
public Map<Time, String> timeKeyMap {
get {
return new Map<Time, String>{timeKey => 'time value'};
}
}
public DateTime dateTimeKey {
get {
return DateTime.newInstance(2012, 1, 1, 0, 0, 0);
}
}
public Map<DateTime, String> dateTimeKeyMap {
get {
return new Map<DateTime, String>{dateTimeKey => 'date time value'};
}
}
public class Custom {
private Integer value;
public Custom(Integer value) {
this.value = value;
}
public Boolean equals(Object other) {
return this.value == ((Custom) other).value;
}
public Integer hashCode() {
return value;
}
}
private static final Custom customInstance = new Custom(321);
public Custom customByReferenceKey {
get {
return customInstance;
}
}
public Map<Custom, String> customByReferenceKeyMap {
get {
return new Map<Custom, String>{customByReferenceKey => 'custom (by reference) value'};
}
}
public Custom customByValueKey {
get {
return new Custom(987);
}
}
public Map<Custom, String> customByValueKeyMap {
get {
return new Map<Custom, String>{customByValueKey => 'custom (by value) value'};
}
}
}
Like this:
Like Loading...