Your code is inappropriately trying to treat a Contact
SObject as a String. On the assumption you want to upper case the Contact names, you could be tempted to do the following:
List<Contact> contacts;
{
contacts = [SELECT Id, Name FROM Contact WHERE someWhereCondition here];
for (Contact contact : contacts) {
contact.Name = contact.Name?.toUpperCase();
}
contacts.sort();
}
I removed the redundant new empty list assignment and improved the for loop by switching to a collection iteration form. Finally, this specifically upper cases the Contact names. I have also used SNO to handle null names safely.
However, as Derek F correctly said, Contact.Name is not writable in this way. There are ways around this. His suggestion to use a formula field is a good one, though here is a code-level alternative:
List<Contact> upperCaseContacts = new List<Contact>();
for (Contact contact : contacts) {
Map<String, Object> fieldsByName = new Map<String, Object>(contact.getPopulatedFieldsAsMap());
fieldsByName.put('Name', contact.Name?.toUpperCase());
upperCaseContacts.add((Contact) JSON.deserialize(JSON.serialize(fieldsByName), Contact.class));
}
contacts = upperCaseContacts;
This is at best a dodge, and is expensive in CPU and memory terms, and really you should go with Derek's suggestion.
By the way, this JSON.deserialize of a serialized map is a great way to build mock data (including formula fields and composite fields) in unit tests when you don't actually want to insert data into a database.
contacts[i] = contacts[i].toUpperCase();
tocontacts[i].Name = contacts[i].Name.toUpperCase()
.