I want to unmarshal the following xml using EclipseLink JAXB (MOXy)
<MyObject>
<Value1>1</Value1>
<Value2>2</Value2>
...
<ValueN>N</ValueN>
<Items>
<Item>
<Value4>4</Value4>
...
<ValueM>M</ValueM>
</Item>
...
</Items>
</MyObject>
Where nodes Value1, Value2, etc, are variables.
For this I use the following class
#XmlRootElement(name="MyObject")
public class MyObject {
public MyObject() {
this.items = new ArrayList<Item>();
}
#XmlPath(".")
#XmlJavaTypeAdapter(MyMapAdapter.class)
private Map<String, String> map = new HashMap<String, String>();
private List<Item> items;
public List<Item> getItems() {
return items;
}
#XmlElementWrapper(name="Items")
#XmlElement(name="Item")
public void setItems(List<Item> items) {
this.items = items;
}
}
Where in MyMapAdapter I get a list of Value nodes and their "values". If I remove the "map" property, then the values of the list are loaded correctly.
This is MyMapAdapter:
public class MapAdapter extends XmlAdapter<MapAdapter.AdaptedMap, Map<String, String>> {
public static class AdaptedMap {
#XmlVariableNode("key")
List<AdaptedEntry> entries = new ArrayList<AdaptedEntry>();
}
public static class AdaptedEntry {
#XmlTransient
public String key;
#XmlValue
public String value;
}
#Override
public AdaptedMap marshal(Map<String, String> map) throws Exception {
AdaptedMap adaptedMap = new AdaptedMap();
for(Entry<String, String> entry : map.entrySet()) {
AdaptedEntry adaptedEntry = new AdaptedEntry();
adaptedEntry.key = entry.getKey();
adaptedEntry.value = entry.getValue();
adaptedMap.entries.add(adaptedEntry);
}
return adaptedMap;
}
#Override
public Map<String, String> unmarshal(AdaptedMap adaptedMap) throws Exception {
List<AdaptedEntry> adaptedEntries = adaptedMap.entries;
Map<String, String> map = new HashMap<String, String>(adaptedEntries.size());
for(AdaptedEntry adaptedEntry : adaptedEntries) {
if(!"Items".equals(adaptedEntry.key)){
map.put(adaptedEntry.key, adaptedEntry.value);
}
}
return map;
}
}
What am I doing wrong? How this can be done?
Any help will be greatly appriciated
Related
I have my DTO class with predefined fields and map for non-mapped. When otherFields map contains field with same name (field1 key) jackson serialize both of them and I have non-valid json like
{
"field1": "value",
"field1": "otherValue"
}
public class DTO implements Serializable {
private String field1;
#JsonIgnore
#JsonAnySetter
private final Map<String, Object> otherFields = new LinkedHashMap<>();
#JsonAnyGetter
public Map<String, Object> getOtherFields() {
return otherFields;
}
public String getField1() {
return field1;
}
public void setField1(String field1) {
this.field1 = field1;
}
}
Is there a way in this case pick one only value? For my case one from map should have priority.
The simplest solution I would propose is to ignore property and in getter marked by JsonAnyGetter annotation add extra logic which would check this condition:
class DTO {
#JsonIgnore
private String field1;
private final Map<String, Object> otherFields = new LinkedHashMap<>();
#JsonAnyGetter
public Map<String, Object> getOtherFields() {
otherFields.putIfAbsent("field1", field1);
return otherFields;
}
#JsonAnySetter
public void setOtherFields(String key, Object value) {
otherFields.put(key, value);
}
public String getField1() {
return field1;
}
public void setField1(String field1) {
this.field1 = field1;
}
}
It is simple, but breaks getter by modifying otherFields Map. We can improve it by adding one classical getter and one for a Jackson:
class DTO {
private String field1;
private final Map<String, Object> otherFields = new LinkedHashMap<>();
#JsonIgnore
public Map<String, Object> getOtherFields() {
return otherFields;
}
#JsonAnyGetter
private Map<String, Object> internalJacksonGetOtherFields() {
otherFields.putIfAbsent("field1", field1);
return otherFields;
}
#JsonAnySetter
public void setOtherFields(String key, Object value) {
otherFields.put(key, value);
}
#JsonIgnore
public String getField1() {
return field1;
}
public void setField1(String field1) {
this.field1 = field1;
}
}
I am building a rest API using Jersey where XML and JSON outputs are allowed depending on what format client prefers(using Accept header).The service sends the below class as an output which looks like this
#XmlRootElement
public class ProjectDetails{
private List<Attachment> attachments;
private Map<String, List<Attachment>> imageCategory;
#XmlTransient
public List<Attachment> getAttachments() {
return attachments;
}
public void setAttachments(List<Attachment> attachments) {
this.attachments = attachments;
}
public Map<String, List<Attachment>> getImageCategory() {
if(attachments == null || attachments.size() == 0){
return null;
}
Map<String, List<Attachment>> map = new HashMap<String, List<Attachment>>();
for (Attachment img : attachments){
String key = img.getCategory();
if(BaseUtil.hasText(key)){
List<Attachment> values = map.get(key);
if (values == null){
values = new ArrayList<Attachment>();
}
values.add(img);
map.put(key, values);
}
}
this.imageCategory = map ;
return imageCategory;
}
public void setImageCategory(Map<String, List<Attachment>> imageCategory) {
this.imageCategory = imageCategory;
}
}
I don't want attachments field as an output so marked it with #XmlTransient rather I want to form a Map using the attachments field and send it as an output.
In case of JSON format, I am getting the correct response.But in case of XML, I am not getting any output when I hit the service.
I think it is related to this Map field because if I remove Map field and add some other field like String then I get that field in response.
Please let me know how to resolve this.
Update:
After some googling, i found XmlAdapter solution and implemented as below
public class MapAdapter extends
XmlAdapter<MapAdapter.AdaptedMap, Map<String, List<Attachment>>> {
public static class AdaptedEntry {
public String key;
public List<Attachment> value = new ArrayList<Attachment>();
}
public static class AdaptedMap {
List<AdaptedEntry> entries = new ArrayList<AdaptedEntry>();
}
#Override
public AdaptedMap marshal(Map<String, List<Attachment>> map)
throws Exception {
AdaptedMap adaptedMap = new AdaptedMap();
for (Entry<String, List<Attachment>> entry : map.entrySet()) {
AdaptedEntry adaptedEntry = new AdaptedEntry();
adaptedEntry.key = entry.getKey();
adaptedEntry.value = entry.getValue();
adaptedMap.entries.add(adaptedEntry);
}
return adaptedMap;
}
#Override
public Map<String, List<Attachment>> unmarshal(AdaptedMap adaptedMap)
throws Exception {
List<AdaptedEntry> adapatedEntries = adaptedMap.entries;
Map<String, List<Attachment>> map = new HashMap<String, List<Attachment>>(
adapatedEntries.size());
for (AdaptedEntry adaptedEntry : adapatedEntries) {
map.put(adaptedEntry.key, adaptedEntry.value);
}
return map;
}
And then
#XmlJavaTypeAdapter(MapAdapter.class)
public Map<String, String> getImageCategory() {
But still it's not working..Anything I missed?
I have used your ProjectDetails class a little bit changes I've made, and it provides response for both XML and JSON. Can you try this?
#XmlRootElement
public class ProjectDetails {
private List<Attachment> attachments;
private Map<String, ArrayList<Attachment>> imageCategory;
#XmlTransient
public List<Attachment> getAttachments() {
return attachments;
}
public void setAttachments(List<Attachment> attachments) {
this.attachments = attachments;
}
#XmlJavaTypeAdapter(MapAdapter.class)
public Map<String, ArrayList<Attachment>> getImageCategory() {
if(attachments == null || attachments.size() == 0){
return null;
}
Map<String, ArrayList<Attachment>> map = new HashMap<String, ArrayList<Attachment>>();
for (Attachment img : attachments){
String key = img.getCategory();
if(!key.equals("")){
ArrayList<Attachment> values = map.get(key);
if (values == null){
values = new ArrayList<Attachment>();
}
values.add(img);
map.put(key, values);
}
}
this.imageCategory = map ;
return imageCategory;
}
public void setImageCategory(Map<String, ArrayList<Attachment>> imageCategory) {
this.imageCategory = imageCategory;
}
}
And the Adapter class you can use the following
public class MapAdapter extends XmlAdapter<MapElement[], Map<String, ArrayList<Attachment>>>{
public MapElement[] marshal(Map<String, ArrayList<Attachment>> arg0) throws Exception {
MapElement[] mapElements = new MapElement[arg0.size()];
int i = 0;
for (Map.Entry<String, ArrayList<Attachment>> entry : arg0.entrySet()){
mapElements[i++] = new MapElement(entry.getKey(), entry.getValue());
}
return mapElements;
}
public Map<String, ArrayList<Attachment>> unmarshal(MapElement[] arg0) throws Exception {
Map<String, ArrayList<Attachment>> r = new HashMap<String, ArrayList<Attachment>>();
for (MapElement mapelement : arg0)
r.put(mapelement.key, mapelement.value);
return r;
}
}
I've changed the MapElement also
public class MapElement {
#XmlElement
public String key;
#XmlElement
public ArrayList<Attachment> value;
private MapElement() {
}
public MapElement(String key, ArrayList<Attachment> value) {
this.key = key;
this.value = value;
}
}
And the Attachement class should have getter setter methods
public class Attachment {
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
private String category;
public Attachment(String cat){
this.category = cat;
}
}
I have the following code:
#XmlRootElement(name = "repository")
#XmlAccessorType(XmlAccessType.FIELD)
public class Repository
{
#XmlElement (name = "id")
private String id;
#XmlElement (name = "policy")
private String policy;
...
}
#XmlRootElement(name = "storage")
#XmlAccessorType(XmlAccessType.FIELD)
public class Storage
{
#XmlElement (name = "id")
private String id;
/**
* K: repository.id
* V: Repository
*/
#XmlElement (name = "repositories")
#XmlJavaTypeAdapter(RepositoryMapAdapter.class)
private Map<String, Repository> repositories = new LinkedHashMap<String, Repository>();
...
}
public class DataCenter
{
/**
* K: storageId
* V: storage
*/
#XmlElement(name = "storages")
#XmlJavaTypeAdapter(StorageMapAdapter.class)
//#XStreamAlias(value = "storages")
private Map<String, Storage> storages = new LinkedHashMap<String, Storage>();
...
}
I have the following two adapters:
public class RepositoryMapAdapter
extends XmlAdapter<RepositoryMapAdapter.RepositoryMap, Map<String, Repository>>
{
public static class RepositoryMap
{
#XmlVariableNode("id")
List<RepositoryMapEntry> entries = new ArrayList<RepositoryMapEntry>();
}
public static class RepositoryMapEntry
{
#XmlAttribute
public String id;
#XmlValue
public Repository repository;
}
#Override
public RepositoryMap marshal(Map<String, Repository> map)
throws Exception
{
RepositoryMap repositoryMap = new RepositoryMap();
for (Map.Entry<String, Repository> entry : map.entrySet())
{
RepositoryMapEntry repositoryMapEntry = new RepositoryMapEntry();
repositoryMapEntry.id = entry.getKey();
repositoryMapEntry.repository = entry.getValue();
System.out.println("Writing repository " + entry.getValue().getId());
repositoryMap.entries.add(repositoryMapEntry);
}
return repositoryMap;
}
#Override
public Map<String, Repository> unmarshal(RepositoryMap repositoryMap)
throws Exception
{
List<RepositoryMapEntry> adaptedEntries = repositoryMap.entries;
Map<String, Repository> map = new LinkedHashMap<String, Repository>(adaptedEntries.size());
for (RepositoryMapEntry repositoryMapEntry : adaptedEntries)
{
System.out.println("Reading repository " + repositoryMapEntry.id);
map.put(repositoryMapEntry.id, repositoryMapEntry.repository);
}
return map;
}
}
public class StorageMapAdapter
extends XmlAdapter<StorageMapAdapter.StorageMap, Map<String, Storage>>
{
public static class StorageMap
{
#XmlVariableNode("id")
List<StorageMapEntry> entries = new ArrayList<StorageMapEntry>();
}
public static class StorageMapEntry
{
#XmlAttribute
public String id;
#XmlValue
public Storage storage;
}
#Override
public StorageMap marshal(Map<String, Storage> map)
throws Exception
{
StorageMap storageMap = new StorageMap();
for (Map.Entry<String, Storage> entry : map.entrySet())
{
StorageMapEntry storageMapEntry = new StorageMapEntry();
storageMapEntry.id = entry.getKey();
storageMapEntry.storage = entry.getValue();
System.out.println("Writing storage " + entry.getValue().getId());
storageMap.entries.add(storageMapEntry);
}
return storageMap;
}
#Override
public Map<String, Storage> unmarshal(StorageMap storageMap)
throws Exception
{
List<StorageMapEntry> adaptedEntries = storageMap.entries;
Map<String, Storage> map = new LinkedHashMap<String, Storage>(adaptedEntries.size());
for (StorageMapEntry storageMapEntry : adaptedEntries)
{
System.out.println("Reading storage " + storageMapEntry.id);
map.put(storageMapEntry.id, storageMapEntry.storage);
}
return map;
}
}
I'd like to have the following XML:
<storages>
<storage id="storage0">
<repositories>
<repository id="repository1" policy="policy1"/>
<repository id="repository2" policy="policy2"/>
</repositories>
</storage>
<storage id="storage1">
<repositories>
<repository id="repository3" />
<repository id="repository4" />
</repositories>
</storage>
</storages>
Based on the above XML, what more do I need to do in order to have my code read/write such XML using JAXB? As far as I understand, I need to use XmlAdapter, but I'm not quite sure how to apply it to this case.
Something in the lines of:
#XmlRootElement(name = "datacenter")
public class DataCenter {
/**
* K: storageId V: storage
*/
#XmlElement(name = "storages")
#XmlJavaTypeAdapter(StorageMapAdapter.class)
private final Map<String, Storage> storages = new LinkedHashMap<String, Storage>();
}
#XmlJavaTypeAdapter(StorageMapAdapter.class)
#XmlAccessorType(XmlAccessType.FIELD)
public class Storage {
#XmlAttribute(name = "id")
private String id;
/**
* K: repository.id V: Repository
*/
#XmlElement(name = "repositories")
#XmlJavaTypeAdapter(RepositoryMapAdapter.class)
private final Map<String, Repository> repositories = new LinkedHashMap<String, Repository>();
}
public class StorageMap {
#XmlElement(name = "storage")
List<Storage> entries = new ArrayList<Storage>();
public List<Storage> getEntries() {
return entries;
}
}
public class StorageMapAdapter extends XmlAdapter<StorageMap, Map<String, Storage>> {
#Override
public StorageMap marshal(Map<String, Storage> map) throws Exception {
StorageMap storageMap = new StorageMap();
for (Map.Entry<String, Storage> entry : map.entrySet()) {
storageMap.getEntries().add(entry.getValue());
}
return storageMap;
}
#Override
public Map<String, Storage> unmarshal(StorageMap storageMap) throws Exception {
List<Storage> adaptedEntries = storageMap.entries;
Map<String, Storage> map = new LinkedHashMap<String, Storage>(adaptedEntries.size());
for (Storage storage : adaptedEntries) {
map.put(storage.getId(), storage);
}
return map;
}
}
#XmlRootElement(name = "repository")
#XmlAccessorType(XmlAccessType.FIELD)
public class Repository {
#XmlAttribute(name = "id")
private String id;
#XmlAttribute(name = "policy")
private String policy;
}
public class RepositoryMap {
#XmlElement(name = "repository")
List<Repository> entries = new ArrayList<Repository>();
public List<Repository> getEntries() {
return entries;
}
}
public class RepositoryMapAdapter extends XmlAdapter<RepositoryMap, Map<String, Repository>> {
#Override
public RepositoryMap marshal(Map<String, Repository> map) throws Exception {
RepositoryMap repositoryMap = new RepositoryMap();
for (Map.Entry<String, Repository> entry : map.entrySet()) {
repositoryMap.getEntries().add(entry.getValue());
}
return repositoryMap;
}
#Override
public Map<String, Repository> unmarshal(RepositoryMap repositoryMap) throws Exception {
List<Repository> adaptedEntries = repositoryMap.entries;
Map<String, Repository> map = new LinkedHashMap<String, Repository>(adaptedEntries.size());
for (Repository repository : adaptedEntries) {
System.out.println("Reading repository " + repository.getId());
map.put(repository.getId(), repository);
}
return map;
}
}
Running demo here: http://ideone.com/NyOGVQ
Demo updated with marshalling here: http://ideone.com/NzvRzX
Following question has been separated from this one:
ArrayIndexOutOfBoundsException while Spring save data to MongoDB
I have problem with saving Object to MongoDB. I've noticed that problem might be caused by too complex object. I have following class hierarchy:
ClassA is superclass for ClassB and ClassC. ClassD contains map of maps. ClassC contains ClassB.
Code which I invoke is following:
ClassC c = new ClassC()
c.setName("NAME");
mongoOperation.save(c, "Mongo"); // MongoOperations object
The problem is that Mongo doesn't save object's data. It saves only _id and _class.
Actual data
{
"_id" : ObjectId("53e86cd9c506f66eafaa03cb"),
"_class" : "com.sample.ClassC"
}
Expected data
{
"_id" : ObjectId("53e86cd9c506f66eafaa03cb"),
"_class" : "com.sample.ClassC",
"name" : "NAME"
}
Funny thing is that when I comment out map field in ClassD everything works fine.
Is it possible to be caused by too complex object which I try to serialize?
EDIT
When I remove bObject from ClassC it also works fine.
EDIT 2
All classes are simple beans with setters and getters.
e.g.
public class ClassD{
private TreeMap<String, TreeMap<String,String>> map;
public TreeMap<String, TreeMap<String, String>> getMap() {
return map;
}
public void setMap(TreeMap<String, TreeMap<String, String>> map) {
this.map = map;
}
}
EDIT 3
Full example below, it has same class hierarchy as picture above.
public class Application implements CommandLineRunner {
#Autowired
private MongoTemplate mongoTemplate;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
public void run(String... args) throws Exception {
ClassC cObject = new ClassC();
cObject.setName("Jon");
try {
mongoTemplate.save(cObject);
}catch(Exception e){
e.printStackTrace();
}
mongoTemplate.save(cObject);
}
}
class ClassA{
private String name;
private ClassD dObject;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ClassD getdObject() {
return dObject;
}
public void setdObject(ClassD dObject) {
this.dObject = dObject;
}
}
class ClassB extends ClassA {
}
class ClassC extends ClassA {
private ClassB b;
public ClassB getB() {
return b;
}
public void setB(ClassB b) {
this.b = b;
}
}
class ClassD {
private TreeMap<String, TreeMap<String, String>> map = new TreeMap<>();
public TreeMap<String, TreeMap<String, String>> getMap() {
return map;
}
public void setMap(TreeMap<String, TreeMap<String, String>> map) {
this.map = map;
}
}
I guess the MongoConverter in specific version of your spring-data-mongodb.jar works incorrectly.
Spring must convert your ClassC instance into DBObject format, then call DBCollection.save to save data into database. You can check the content of DBObject parameter in method "com.mongodb.DBCollection.save" whether it contains correct data as you expect.
I copy your ClassC with complete structure and test, it's fine and cannot reproduce what you described above. I use spring-data-mongdb-1.2.3-RELEASE.jar. What's the version you adopt?
The following code seems to work:
#EnableAutoConfiguration
public class Application implements CommandLineRunner {
#Autowired
private MongoTemplate mongoTemplate;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
public void run(String... args) throws Exception {
Customer customer = new Customer("myself");
ClassB classB = new ClassB();
TreeMap<String, TreeMap<String, String>> map = new TreeMap<String, TreeMap<String, String>>();
TreeMap<String, String> innermap = new TreeMap<String, String>();
innermap.put("iam", "cool");
map.put("innermap", innermap);
TreeMap<String, String> innermap2 = new TreeMap<String, String>();
innermap2.put("youare", "yellow");
map.put("innermap2", innermap2);
classB.setMap(map);
customer.setClassB(classB);
try {
mongoTemplate.save(customer);
} catch (Exception e) {
e.printStackTrace();
}
mongoTemplate.save(customer);
System.out.println(mongoTemplate.findAll(Customer.class));;
}
}
public class ClassB {
private TreeMap<String, TreeMap<String, String>> map = new TreeMap<String, TreeMap<String, String>>();
public TreeMap<String, TreeMap<String, String>> getMap() {
return map;
}
public void setMap(TreeMap<String, TreeMap<String, String>> map) {
this.map = map;
}
}
#Document(collection ="customer")
public class Customer {
#Id
private String id;
private String name;
private ClassB classB;
public Customer() {
}
public Customer(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ClassB getClassB() {
return classB;
}
public void setClassB(ClassB classB) {
this.classB = classB;
}
#Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", classB=" + classB
+ "]";
}
}
But the ArrayIndexOutOfBoundsException-issue is still present.
I would like to be able to test if a List contain an object with a given key-value
For example, I would like to do something like Iterables.contains(l2, "lname", "Jordan")); instead of having to create all other Map objects like below in l2
//List<String> l = Arrays.asList("Mickael", "Jordan", "His Airness");
//System.out.println(Iterables.contains(l, "Jordan"));
Map<String, String> p1 = new HashMap<String, String>();
p1.put("fname", "Mickael");
p1.put("lname", "Jordan");
p1.put("nname", "His Airness");
Map<String, String> p2 = new HashMap<String, String>();
p2.put("fname", "Paul");
p2.put("lname", "Pierce");
p2.put("nname", "The Truth");
List<Map<String, String>> l2 = Arrays.asList(p1, p2);
Map<String, String> p3 = new HashMap<String, String>();
p3.put("fname", "Mickael"); //
p3.put("lname", "Jordan");
p3.put("nname", "His Airness"); //
System.out.println(Iterables.contains(l2, p3));
I'd like to know if there's such guava's function, and not doing a loop on l2 and testing each elt.get("lname")
Edit
3 solutions answered: trying to see which one is more perfomant
System.out.println(Iterables.any(l2, withEntry("lname", "Jordan"))); //#axtavt
System.out.println(has("lname", "Jordan")); //#JB
System.out.println(Iterables.any(l2, new KeyValuePredicate("lname", "Jordan"))); //#JB
public static Boolean has(final String key, final String value) {
return Iterables.any(l2, new Predicate<Map<String, String>>() {
#Override
public boolean apply(Map<String, String> input) {
return input.get(key).equals(value);
}
});
}
public static Predicate<Map<String, String>> withEntry(final String key, final String value) {
return new Predicate<Map<String, String>>() {
public boolean apply(Map<String, String> input) {
return value.equals(input.get(key));
}
};
}
class KeyValuePredicate implements Predicate<Map<String, String>>{
private String key;
private String value;
public KeyValuePredicate(String key, String value) {
super();
this.key = key;
this.value = value;
}
#Override
public boolean apply(Map<String, String> arg0) {
// TODO Auto-generated method stub
return arg0.get(key).equals(value);
}
}
return Iterables.any(l2, new Predicate<Map<String, String>>() {
#Override
public boolean apply(Map<String, String> input) {
return input.get("lname").equals("Jordan");
}
});
But you're using maps when you should use objects with properties.
Of course, if you need to do that multiple times, with various properties, you should transform the predicate into a non-anonymous, reusable class:
return Iterables.any(l2, new KeyValuePredicate("lname", "Jordan"));
You can implement an appropriate Predicate and use Iterables.any():
public Predicate<Map<String, String>> withEntry(final String key, final String value) {
return new Predicate<Map<String, String>>() {
public boolean apply(Map<String, String> input) {
return value.equals(input.get(key));
}
};
}
System.out.println(Iterables.any(l2, withEntry("lname", "Jordan")));
Well this is straightforward.
You should create a proper entity class:
public class Person {
private String fName;
private String lName;
private String nName;
public Person(String fName, String lName, String nName) {
this.fName = fName;
this.lName = lName;
this.nName = nName;
}
public String getFName() {
return fName;
}
public String getLName() {
return lName;
}
public String getNName() {
return nName;
}
}
Then you can do the following:
import java.util.*;
public class Test {
public static void main (String [] args) {
List<Person> list = new ArrayList<Person>();
Person p1 = new Person("Mickael", "Jordan", "His Airness");
for (Person person : list) {
if (person.getFName().equals("Mickael")) {
System.out.println("Mickael is in the list!");
break;
}
}
}
}