I'm trying to deserialize a JSon object with an Anroid app, but can't get it running. The intention is to read data from an asset item ("AllPoloniexPairs.txt"), which is the JSON objrct I'm trying to deserialyze and get "currencyPairs" from the Data part and put it into the spinner.
Below is (part of) my JSON
{"BTC_BCN":{"id":7,"baseID":28,"quoteID":17,"base":"BTC","quote":"BCN","currencyPair":"BTC_BCN"},"BTC_BTS":{"id":14,"baseID":28,"quoteID":32,"base":"BTC","quote":"BTS","currencyPair":"BTC_BTS"}}
This is my code
public class Data
{
public int id { get; set; }
public int baseID { get; set; }
public int quoteID { get; set; }
public string Base { get; set; }
public string Quote { get; set; }
public string currencyPair { get; set; }
}
public class Pairs
{
public string id { get; set; }
public Data data { get; set; }
}
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
using (StreamReader sr = new StreamReader(assets.Open("AllPoloniexPairs.txt")))
{
content = sr.ReadToEnd();
}
Pairs pairs = JsonConvert.DeserializeObject<Pairs>(content);
ArrayAdapter<String> adapter;
Spinner spinner2 = (Spinner)FindViewById(Resource.Id.spinner2);
List<string> spinnerItems = new List<string>();
foreach (var k in pairs.data.currencyPair)
{
spinnerItems.Add(k.ToString());
}
spinnerItems.Sort();
adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleSpinnerDropDownItem, spinnerItems);
spinner2.Adapter = adapter;
}
When I skip the foreach loop the app runs, but of course with no items in the spinner. If I include the foreach part, the application hangs.
I have tried several things now for the last couple of hours, but without any luck.
What could be the reason that the code doesn't run?
Well why do you reinvent the wheel google has already done it for you you can do it in two lines of code:
https://github.com/google/gson
Gson gson = new Gson();
MyClass myClass= gson.fromJson(json, MyClass.class);
Well sorry for the delay was figuring your json data and it seems wrong to me and GSON you better use something like :
[
{
"id": 7,
"baseID": 28,
"quoteID": 17,
"base": "BTC",
"quote": "BCN",
"currencyPair": "BTC_BCN"
},
{
"id": 14,
"baseID": 28,
"quoteID": 32,
"base": "BTC",
"quote": "BTS",
"currencyPair": "BTC_BTS"
}
]
You were using an object which has two objects in it.
That's not an array remember array should have brackets.
Now let's do this with the above json we have a class called MyClass let's say:
public class MyClass {
int id;
int baseID;
int quoteID;
String base;
String quote;
String currencyPair;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getBaseID() {
return baseID;
}
public void setBaseID(int baseID) {
this.baseID = baseID;
}
public int getQuoteID() {
return quoteID;
}
public void setQuoteID(int quoteID) {
this.quoteID = quoteID;
}
public MyClass(String currencyPair) {
this.currencyPair = currencyPair;
}
public String getBase() {
return base;
}
public void setBase(String base) {
this.base = base;
}
public String getQuote() {
return quote;
}
public void setQuote(String quote) {
this.quote = quote;
}
}
Now in your activity use:
Gson gson = new Gson();
String jsonOutput = "[{\"id\":7,\"baseID\":28,\"quoteID\":17,\"base\":\"BTC\",\"quote\":\"BCN\",\"currencyPair\":\"BTC_BCN\"},{\"id\":14,\"baseID\":28,\"quoteID\":32,\"base\":\"BTC\",\"quote\":\"BTS\",\"currencyPair\":\"BTC_BTS\"}]";
MyClass[] posts = gson.fromJson(jsonOutput, MyClass[].class);
Log.v("SteveMoretz", String.valueOf(posts.length));
You will get 2 by the Log which means you have two objects now you can use where ever you want.:)
Related
for two days I have been trying to understand how to move this JSON to an object in C#. I read a lot of topics and tried several ways to solve my problem, but still haven't solved it.
My JSON looks like this (cropped).
{
"data": [{
"id": 5643793,
"title": "It's a Title",
"description": "It's a Description.",
"tags": "#tag1 #tag2 #tag3 #tag4",
"source_url": "https:\/\/p.dw.com\/p\/3geny",
"vote_count": 120,
"bury_count": 17,
"comments_count": 33,
"related_count": 0,
"date": "2020-08-10 09:43:32",
"author": {
"login": "lnwsk",
"color": 2,
"avatar": "https:\/\/www.api.page.com\/cdn\/c3397992\/lnwsk_MfQz8MEQb2,q150.jpg"
},
"preview": "https:\/\/www.api.page.com\/cdn\/c3397993\/link_1597045214DgzqxRGEmy2UlpPZwaWfhI,w104h74.jpg",
"plus18": false,
"status": "promoted",
"can_vote": true,
"is_hot": false
}],
"pagination": {
"next": "https:\/\/api.page.com\/links\/promoted\/appkey\/X*******4y\/page\/2\/"
}
}
As you can see, there is an "element within an element" here (eg author or pagination (eg pagination I would like to get rid of)) and that is what gives me the most problem.
Here is my class where I have all the code to read the API:
using Newtonsoft.JSON;
public class PageAPI
{
public class Product
{
public string[] title { get; set; }
public double[] description { get; set; }
public string[] tags { get; set; }
public string[] source_url { get; set; }
public string[] vote_count { get; set; }
public string[] bury_count { get; set; }
public string[] comments_count { get; set; }
public string[] related_count { get; set; }
public string[] date { get; set; }
}
public async Task<Product> GetDataAsync()
{
string url = "https://api.page.com/";
string apisign = "6*********c1fe49a23f19ad6b2";
string requestParams = "links/promoted/appkey/X*******y";
Product obj = null;
// HTTP GET.
using (var client = new HttpClient())
{
// Setting Base address.
client.BaseAddress = new Uri(url);
// Setting content type.
client.DefaultRequestHeaders.Add("apisign", apisign);
// Initialization.
HttpResponseMessage response = new HttpResponseMessage();
// HTTP GET
response = await client.GetAsync(requestParams).ConfigureAwait(false);
// Verification
if (response.IsSuccessStatusCode)
{
try
{
// Reading Response.
string result = response.Content.ReadAsStringAsync().Result;
obj = JsonConvert.DeserializeObject<Product>(result);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
MessageBox.Show(ex.Message);
}
}
else
{
obj = null;
}
}
return obj;
}
}
in the Form where I want to get data from the "PageAPI" class I have:
private async void Form1_LoadAsync(object sender, EventArgs e)
{
var task = api.GetMainAsync();
task.Wait();
var data = task.Result;
label1.Text = data.title[0];
}
And... this doesn't works - on label1.Text = data.title[0]; i get error PageAPI.Product.title.get returned null
Thanks for any help!
You are missing the Root class that has "data" and "pagination" properties. Create Root class and deserialize to it and then get the data you need. Also, your Product class will have only strings.. not string[].
public class RootObject
{
public List<Product> data { get; set; }
}
public class Product
{
public string title { get; set; }
public double description { get; set; }
public string tags { get; set; }
public string source_url { get; set; }
public string vote_count { get; set; }
public string bury_count { get; set; }
public string comments_count { get; set; }
public string related_count { get; set; }
public string date { get; set; }
}
// and deserialize it
var rootObj = JsonConvert.DeserializeObject<RootObject>(result);
obj = rootObj.data.FirstOrDefault();
data object is an array ... you can loop through it to work with All the items. In above example, i used FirstOrDefault() to get the first item from the object.
Also note that when you access this data, you would not access it via [0]. Simply use
label1.Text = data.title;
Side Note
If you want the pagination property as well, create another class to get the name from pagination object.
public class RootObject {
public List<Product> data {get;set;}
public Pagination pagination {get;set;}
}
public class Pagination {
public string next {get;set; }
}
and when you deserialize your json, you would access the pagination by using,
Console.WriteLine(rootObj.pagination.next); // prints the url
How to get All the Product Names displayed
This is how you would go about getting a list of All the titles in the data object.
foreach (var product in rootObj.data)
{
Console.WriteLine(product.title);
Console.WriteLine(product.description);
Console.WriteLine(product.vote_count); // etc.
}
// Or you can create a list of all the titles from the rootObj using LINQ
List<string> allTitles = rootObj.data.Select(x => x.title).ToList();
I am not sure what you intend to do with the data you get... so not sure how to explain that piece.. but above example should give you an idea on how to iterate through all the products in the data object.
In this code here I set the values to model classes from JSON file called myJson.code works fine and values binding to the model classes without any issues. My code as follows.
class Program
{
static void Main(string[] args)
{
ReadJson();
}
public static string ReadJson()
{
string case20 = "this is 20", case40 = "this is 40";
string json;
using (StreamReader r = new StreamReader(#"C:\Users\HP\Desktop\Output\myJson.json"))
{
json = r.ReadToEnd();
}
MyClass response = JsonConvert.DeserializeObject<MyClass>(json);
var dropDowns = response;
string jsonDropdown = JsonConvert.SerializeObject(dropDowns, Formatting.Indented);
return "";
}
}
Here is my model classes:
public class Customer
{
public int RATE { get; set; }
public int FEE { get; set; }
public int PERIOD { get; set; }
public string NewValue
{
get
{
var rateVal = this.RATE;
switch (rateVal)
{
case 20:
return ""; // Here, I need to get value from the ReadJson method to return (value of case20)
case 40:
return ""; // Here, I need to get value from the ReadJson method to return (value of case40)
}
return "test";
}
}
}
public class MyClass
{
public string StatusCode { get; set; }
public Customer Customer { get; set; }
public object LoanDetail { get; set; }
}
After I set the values to model classes,from the Customer class I want to check the RATE and in order to the value of the RATE I want to return value of the case20 and case40 variable's value in the ReadJson() method. How can I access those value form Customer class.
Thanks in advance!!!
Updated:
This is sample JSON string
{
"StatusCode": "100",
"Customer": {
"RATE": 20,
"FEE": 3000,
"PERIOD": 60,
"NewValue":""
},
"LoanDetail": null
}
According to belove JSON string, My output should be
{
"StatusCode": "100",
"Customer": {
"RATE": 20,
"FEE": 3000,
"PERIOD": 60,
"NewValue":"this is 20"
},
"LoanDetail": null
}
Your functions are reading the JSON data from the string into your customer object.
Shouldn't the case20 & case40 be set in the customer object or program themselves?
You are not reading into the case20 or 40 strings from the JSON anywhere I could see. So I am assuming that their output does not change dynamically when running the program.
Also your var rateVale = this.rate; should be something like var rateVal = int.Parse(this.rate); as you are comparing it as an integer. either that or switch cases should be "20" not 20 etc.
Can you include an example of the code you have and what the appropriate object values should be and the output of the newValue parameter please?
Change your code according below and it does what you want. But I still cant understand why you need NewValue property while you have already RATE property. Does not they carrying same value? You setting NewValue based on RATE, why dont you use just RATE everywhere?
public static string ReadJson()
{
string json = File.ReadAllText(#"C:\Users\HP\Desktop\Output\myJson.json");
MyClass response = JsonConvert.DeserializeObject<MyClass>(json);
return JsonConvert.SerializeObject(response, Formatting.Indented);
}
public class Customer
{
public int RATE { get; set; }
public int FEE { get; set; }
public int PERIOD { get; set; }
public string NewValue
{
get
{
switch (RATE)
{
case 20:
return "this is 20";
case 40:
return "this is 40";
default:
return "";
}
}
}
}
public static void Main(string[] args)
{
Console.WriteLine(ReadJson());
}
The output is :
{
"StatusCode": "100",
"Customer": {
"RATE": 20,
"FEE": 3000,
"PERIOD": 60,
"NewValue": "this is 20"
},
"LoanDetail": null
}
Thanks to everyone who helped me to solve this. I found the solution to solve my problem.
I created a static class, called TestCase.
public static class TestCase
{
public static string case20 { get; set; }
public static string case40 { get; set; }
}
Then set the values to those fields within the ReadJson()
public static string ReadJson()
{
TestCase.case20 = "this is 20";
TestCase case40 = "this is 40";
// same code has beign used....
}
Then within the Customer class, I accessed those values as follows.
public class Customer
{
public int RATE { get; set; }
public int FEE { get; set; }
public int PERIOD { get; set; }
public string NewValue
{
get
{
switch (RATE)
{
case 20:
return TestCase.case20;
case 40:
return TestCase.case40;
default:
return "";
}
}
}
}
My Service returns a JSON like below, I want to Parse this and bind category_name to my list, how to do this in C#, UWP apps.
Iam trying to Deserialize this in this way
var content_resp = await response.Content.ReadAsStringAsync();
content_resp = "{ \"root\": " + content_resp.Trim().TrimStart('{').TrimEnd('}') + " }";
var xmlProducts = JsonConvert.DeserializeXNode(content_resp);
var xmlProductNodes = xmlProducts.DescendantNodes();
foreach (XElement xmlProduct in xmlProductNodes)
{
Places pl = new Places();
var node = xmlProducts.Element("category_parent").Value;
pl.category_name = xmlProducts.Element("category_name").Value;
}
}
catch (Exception ex)
{
//throw or return an appropriate response/exception
}
when the debuger comes at this line
var xmlProducts = JsonConvert.DeserializeXNode(content_resp);
it is giving an error like
"This operation would create an incorrectly structured document."
The easiest way that I have found is to use Newtonsoft.Json
Firstly you should create class with data equal to your JSON:
public class AppsData
{
private string _category_id;
private string _category_name;
public string category_id
{
get { return _category_id; }
set { _category_id = value; }
}
public string category_name
{
get { return _category_name; }
set { _category_name = value; }
}
}
Then you can create some helper class:
static class JSONhelper
{
public static IList<T> DeserializeToList<T>(string jsonString)
{
var array = Newtonsoft.Json.Linq.JArray.Parse(jsonString);
IList<T> objectsList = new List<T>();
foreach (var item in array)
{
try
{
objectsList.Add(item.ToObject<T>());
}
catch { }
}
return objectsList;
}
}
Then create instance of List
IList<AppsData> appsdata;
and try to deserialize:
appsdata = JSONhelper.DeserializeToList<AppsData>(stringWithJSON);
If there is no reason to deserialize to XML you can do the following:
Create the class to parse
public class Product
{
public string category_id { get; set; }
[JsonProperty("0")]
public string Zero { get; set; }
public string category_name { get; set; }
[JsonProperty("1")]
public string One { get; set; }
public string category_details { get; set; }
[JsonProperty("2")]
public string Two { get; set; }
public string category_link { get; set; }
[JsonProperty("3")]
public string Three { get; set; }
}
And then
var products = JsonConvert.DeserializeObject<IList<Product>>(your json);
Trying to get the result from a webservice call to return a Model. I eep getting the error:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'CI.Models.Schedule' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
public Schedule getCourseSchedule()
{
var obj = new
{
States = new[] { new { State = "MX" } },
Zip = "",
Miles = "",
PaginationStart = 1,
PaginationLimit = 3
};
using (var client = new WebClient())
{
client.Headers[HttpRequestHeader.ContentType] = "apoplication/json";
var url = "http://192.168.1.198:15014/ShoppingCart2/CourseSchedule";
var json = JsonConvert.SerializeObject(obj);
byte[] data = Encoding.UTF8.GetBytes(json);
byte[] result = client.UploadData(url, data);
string returnjson = Encoding.UTF8.GetString(result);
Schedule sched = JsonConvert.DeserializeObject<Schedule>(returnjson);
return sched;
}
}
Schedule Model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Globalization;
namespace CI.Models
{
public class Schedule
{
public IEnumerable<Course> Courses { get; set; }
}
public class Course
{
/*
JSON Data returned from web service:
{
"ProgramGroup":"MR",
"ProgramCode":"RM",
"EventCode":"20160901MXMR",
"FormalDate":"September 1-2, 2016",
"StartDate":"2016\/09\/01",
"Price":5,
"LocName":"WB Hotel",
"LocAddress":"Av. Speedy Gonzales 220",
"LocCity":"Monterrey",
"LocState":"MX",
"LocZipCode":null,
"LicenseeURL":null,
"AgendaURL":"NA",
"SeatsAreAvailable":"2",
"GeneralInfoHTML":"General Info goes here.",
"GateKeeperHTML":null,
"EventType":"SS",
"TotalCourses":3
}
*/
public string ProgramGroup { get; set; }
public string ProgramCode { get; set; }
public string EventCode { get; set; }
public string FormalDate { get { return FormalDate; } set { FormalDate = convertFormalDateToSpanish(value); } }
public string StartDate { get; set; }
public double Price { get; set; }
public string LocName { get; set; }
public string LocAddress { get; set; }
public string LocCity { get ; set; }
public string LocState { get; set; }
public string LocZipCode { get; set; }
public string LicenseeURL { get; set; }
public string AgendaURL { get { return AgendaURL; } set { AgendaURL = buildAgendaLink(value); } }
public string SeatsAreAvailable { get; set; }
public string GeneralInfoHTML { get; set; }
public string GateKeeperHTML { get; set; }
public string EventType { get; set; }
public int TotalCourses { get; set; }
public string convertFormalDateToSpanish(string val)
{
DateTime TheDate = DateTime.Parse(StartDate);
string[] FormalDate = val.Split(" ".ToCharArray());
CultureInfo ci = new CultureInfo("es-ES");
string _Date = FormalDate[1].Replace("-", " al ").Replace(",", "");
string _Month = ci.TextInfo.ToTitleCase(TheDate.ToString("MMMM", ci));
val = string.Concat(_Date, " ", _Month);
return val;
}
private string buildAgendaLink(string val)
{
if (val.Trim() != "")
{
val = string.Concat("Agenda");
}
else
{
val = "Agenda";
}
return val;
}
}
}
Your server returns an array. Just try
Course[] courses = JsonConvert.DeserializeObject<Course[]>(returnjson);
Note that this is not an answer to your original problem, but I added it like an answer in order to explain my comment above with some actual code.
First problem with your code is that FormalDate and AgendaUrl properties simply won't work. Accessing them will result in a StackOverflowException, because you basically defined them recursively.
A property is merely syntax sugar for two separate getter/setter methods, so by writing this:
public class Course
{
public string FormalDate
{
get { return FormalDate; }
}
}
You are basically writing this:
public class Course
{
public string GetFormalDate()
{
// recursive call, with no terminating condition,
// will infinitely call itself until there is no
// more stack to store context data (and CLR
// will then throw an exception)
return GetFormalDate();
}
}
To fix that, you need to add an actual backing field, e.g.:
public class Course
{
private string _formalDate; // <-- this is a backing field;
// and this property uses the backing field to read/store data
public string FormalDate
{
get { return _formalDate; }
set { _formalDate = convertFormalDateToSpanish(value); }
}
}
Additionally, it's unusual for a property getter to return a different value than the one set through a setter. In other words, I would never expect this from a class:
var course = new Course();
course.StartDate = "2016/09/01";
course.FormalDate = "September 1-2, 2016";
Console.WriteLine(course.FormalDate); // prints "1 al 2 Septiembre" ?
I would rather move this functionality into a different class, or at least create different properties which return these values:
public class CourseInfo
{
// this is now a "dumb" auto-implemented property
// (no need for a backing field anymore)
public string FormalDate { get; set; }
// this read-only property returns the converted value
public string LocalizedFormalDate
{
get
{
return convertFormalDateToSpanish(FormalDate);
}
}
}
i am working on a small app that mange flights, i have a class that build a flight details and class that build the passenger, now, i want to load the passengers onto a flight, how should i do it? do i need to build a higer class that inherit from this two class and make a list of that type of class(i dont think that wise oop ).or should i add a ticket prop in the passenger class that have the flight number, here is my code.
public class Passenger
{
public Passenger(string name, int passportNumber)
{
this.PassengerName = name;
this.PassportNumber = passportNumber;
}
private string _passengerName;
public string PassengerName
{
get { return _passengerName; }
set { _passengerName = value; }
}
private int _passportNumber;
public int PassportNumber
{
get { return _passportNumber; }
set { _passportNumber = value; }
}
}
public class FlightDetails
{
public FlightDetails(int flightNumber, string flightDestination, string planmodel)
{
this.FlightNumber = flightNumber;
this.FlightDestination = flightDestination;
this.PlanModel = planmodel;
}
private int _flightNumber;
public int FlightNumber
{
get { return _flightNumber; }
set { _flightNumber = value; }
}
private string _flightDestination;
public string FlightDestination
{
get { return _flightDestination; }
set { _flightDestination = value; }
}
private string _planeModel;
public string PlanModel
{
get { return _planeModel; }
set { _planeModel = value; }
}
}
static void Main(string[] args)
{
List<FlightDetails> flightList = new List<FlightDetails>();
FlightDetails a = new FlightDetails(12,"france","jumbo");///create a flight
flightList.Add(a);/// load up the flight
}
First, you can't create a class that inherits from both other classes because multiply inheritance is not allowed in C#.
You can use aggregation, something like this:
public class FlightDetails
{
// ...
}
public class Passenger
{
// ...
}
public class Flight
{
public FlightDetails { get; private set; }
public List<Passenger> Passengers { get; private set; }
public Flight(FlightDetails details)
{
FlightDetails = details;
Passengers = new List<Passenger>();
}
public AddPassenger(Passenger p)
{
// check for ticket and so on..
Passengers.Add(p);
}
}
You can read more about aggregation here: http://en.wikipedia.org/wiki/Object_composition#Aggregation
Note that in this example for simplicity i used List but actually you need to limit access to this array (because otherwise i can do something like this: Flight.Passengers.Add(p) instead of Flight.AddPassenger(p)) so good idea will be use ReadOnlyCollection as public interface to this list.
Here's a sample code that might work. A flight has one or more passengers, thus has a List of type Passenger. In real-life, a passenger can book multiple flights. If you want the reality, you'll have to change your model but for this situation it'll work:
public class Passenger
{
public Passenger(string name, int passportNumber)
{
PassengerName = name;
PassportNumber = passportNumber
}
public string PassengerName { get; set; }
public int PassportNumber { get; set; }
}
public class FlightDetails
{
public FlightDetails(int flightNumber, string flightDestination, string planmodel)
{
FlightNumber = flightNumber;
FlightDestination = flightDestination;
PlanModel = planmodel;
Passengers = new List<Passengers>();
}
public int FlightNumber { get; set; }
public string FlightDestination { get; set; }
public string PlanModel { get; set; }
public List<Passenger> Passengers { get; private set; }
public void AddPassenger(string name, int number)
{
int max = 2;
int passengersNumber = Passengers.Count;
if (passengersNumber < max)
{
Passengers.Add(new Passenger(name, number);
}
}
public static void Main(string[] args)
{
var flightList = new List<FlightDetails>();
var passengersList = new List<Passenger>();
//Add passenger-objects to passengers-list
var flightOne = new FlightDetails(12, "France", "Jumbo");
flightOne.Passengers = passengersList;
flightList.Add(a);
}
Here's a better solution to limit the passengers:
public class FlightDetails
{
public FlightDetails(int flightNumber, string flightDestination, string planmodel)
: this(flightNumber, flightDestination, planmodel, new List<Passenger>())
{
}
public FlightDetails(int flightNumber, string flightDestination, string planmodel, List<Passenger> passengers)
{
FlightNumber = flightNumber;
FlightDestination = flightDestination;
PlanModel = planmodel;
if(passengers.Count > 2)
//throw exception or error
else
_passengers = passengers;
}
private List<Passenger> _passengers = new List<Passenger>();
public int FlightNumber { get; set; }
public string FlightDestination { get; set; }
public string PlanModel { get; set; }
public IEnumerable<Passenger> Passengers { get { return _passengers; } }
public void AddPassenger(string name, int number)
{
int max = 2;
int passengersNumber = _passengers.Count;
if (passengersNumber < max)
{
_passengers.Add(new Passenger(name, number);
}
}
}
Note: this code is written without compiling. But the idea is correct normally. :)
In logical way, relation between FlightDetail to Passenger is OneToMany. One FlightDetail can have multiple Passenger which is can be written as below. FlightDetail and Passenger should be have any common inheritance hierarchy because they are don't have any common attribute or behaviour.
public class FlightDetails
{
private List<Passenger> passengerList;
public void addPassenger(Passenger p){
if(passengerList == null){
passengerList = new ArrayList<Passenger>();
}
passengerList.add(p);
}
public List<Passenger> getPassengerList(){
return passengerList;
}
//... your other detail
}
You should add a FlightDetails property to your Passenger class. That's easier than making a List with PassportNumber as index. But, it's easier to iterate FlightDetails using List, than accessing it through Passenger.
It actually depends on how you want to access and store the relations.
It might be a good idea to read about the composite pattern which actually has a nice solution for travelling between parent-child relations, even though the pattern has another purpose.