Is it possible to make not lazy initialization of static properties of class? - static

A brief example of what I am trying to achieve:
class Country {
final int id;
final String name;
static List<Country> values = new List<Country>();
static final Country US = new Country._create(1, 'United States');
static final Country UK = new Country._create(2, 'United Kingdom');
Country._create(this.id, this.name) {
values.add(this);
}
}
I have a Country class with a private named constructor. I want to create a set of static Country constants and a list of all available countries.
And that's the problem:
void main() {
print('Countries:');
for (Country country in Country.values) {
print(country.name);
}
}
Because of static members' lazy initialization my values list is empty. However:
void main() {
print('US id is: ${Country.US.id}');
print('Countries:');
for (Country country in Country.values) {
print(country.name);
}
}
US constant is added to the list only when I refer it in code.
What is the easiest way to fill my static country list with countries without adding them one by one?

Just use a list literal instead of adding it in the constructor:
class Country {
final int id;
final String name;
static List<Country> values = <Country>[US, UK];
static const Country US = new Country._create(1, 'United States');
static const Country UK = new Country._create(2, 'United Kingdom');
Country._create(this.id, this.name);
}
This way you also can use const to improve efficiency
class Country {
final int id;
final String name;
static const List<Country> values = const <Country>[US, UK];
static const Country US = const Country._create(1, 'United States');
static const Country UK = const Country._create(2, 'United Kingdom');
const Country._create(this.id, this.name);
}

Related

How to call correctly a String splitting method from another class?

Im trying to access the Spring splitting method from Person class in Main class, but it doesn't show me only the last result from the text. Its working very good when im integrating System.out.prinln in Person class, in method body but In this homework im not aloud to use System.out in Person class, only in Main class. The result must split the text in "Surname , Name , City". Where am i doing wrong? Thank you!
public class Person {
public String surname;
public String name;
public String city;
public Person(String text) {
String[] person = text.split(" ");
for (int i = 0; i < person.length; i++) {
String surname = person[i].split("[.]")[0];
String name = person[i].split("[./]")[1];
String city = person[i].split("/")[1];
this.surname = surname;
this.name = name;
this.city = city;
}
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person("John.Davidson/Berlin Michael.Barton/Rome Ivan.Perkinson/Munich");
System.out.println(p1.surname + p1.name + p1.city);
// the result is the only the last persons info
}
}

how to output a value from Array of classes in C#

I am trying to display a value from an Array of classes as follows:
class Person
{
private int age;
private string name;
public Person(string Name, int Age)
{
this.name = Name;
this.age = Age;
}
}
class Program
{
static void Main(string[] args)
{
Console.Write("No. of family members: ");
int NoOfEntities = Convert.ToInt32(Console.ReadLine());
Person[] people = new Person[NoOfEntities];
for (int person = 0; person < people.Length; person++)
{
Console.Write($"\nName of No. {person + 1} member: ");
string Name = Console.ReadLine();
Console.Write($"\nAge of No. {person + 1} member: ");
int Age = Convert.ToInt32(Console.ReadLine());
people[person] = new Person(Name, Age);
}
Console.WriteLine(people[0].Age);
}
}
but the compiler complains that 'Person' does not contain a definition for 'Age'. All of the examples I found on internet are using the same method to iterate over the array members. What am I doing wrong?
In your 'Person' class, you have defined age and name as private fields, so they are not accessible from outside of the class (that is why you getting the compiler error). Also note that C# is case sensitive, so age is not the same as Age.
In C# it is common to use public properties for data. It is also common to use names that start with lower case letters for function parameters and local variables. So you probably want your Person class to look like this:
class Person
{
public int Age { get; set; }
public string Name { get; set; }
public Person(string name, int age)
{
this.Name = name;
this.Age = age;
}
}

Sort a dart list based on constructor parameter

I have defined a class like this,
class Person {
final int id,
final String name,
final String email,
final int age,
Person({
this.id,
this.name,
this.email,
this.age});
}
I have a list of Person like,
List<Person> persons;
Now, I need to sort this list as per its constructor parameters like id or age. How can I do that?
You should do that with sort method.
Here's a simple example, sorting the list by the Person name:
class Person {
final int id;
final String name;
final String email;
final int age;
Person({
this.id,
this.name,
this.email,
this.age});
#override
String toString() {
return "Person $name";
}
}
void main () {
List<Person> people = new List();
people
..add(Person(name: "B"))
..add(Person(name: "A"))
..add(Person(name: "D"))
..add(Person(name: "C"));
people.sort((p1, p2) => p1.name.compareTo(p2.name));
print(people);
}
Output:
[Person A, Person B, Person C, Person D]

Android Room Persistence Library - Many to Many Relation

I am trying to achieve many-to-many relationship in Room Persistence Library. I am trying to create a Notes App with Tags.
The idea is:
A note will have multiple tags.
A tag will have multiple notes.
Show all notes in RecyclerView along with Tags.
To achieve this, I have created two models Note.java, Tag.java and TagJoin model to store the relationship b/w notes and tags. Achieving one-to-one is very easy using #Relation annotation.
Here are my models
#Entity(tableName = "notes")
public class Note {
#PrimaryKey
#NonNull
public final String id;
#ColumnInfo(name = "note")
public String note;
#Ignore
public List<Tag> tags;
#Ignore
public Note(String note) {
this(UUID.randomUUID().toString(), note);
}
public Note(String id, String note) {
this.id = id;
this.note = note;
}
public String getId() {
return id;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public List<Tag> getTags() {
return tags;
}
public void setTags(List<Tag> tags) {
this.tags = tags;
}
#Entity(tableName = "note_tag_join",
primaryKeys = {"noteId", "tagId"},
foreignKeys = {
#ForeignKey(
entity = Note.class,
parentColumns = "id",
childColumns = "noteId",
onDelete = CASCADE),
#ForeignKey(
entity = Tag.class,
parentColumns = "id",
childColumns = "tagId",
onDelete = CASCADE)},
indices = {
#Index(value = "noteId"),
#Index(value = "tagId")
}
)
public static class TagJoin {
#NonNull
public final String noteId;
#NonNull
public final String tagId;
public TagJoin(String noteId, String tagId) {
this.noteId = noteId;
this.tagId = tagId;
}
}
}
Tags Model:
#Entity(tableName = "tags", indices = {#Index(value = "name", unique = true)})
public class Tag {
#PrimaryKey
#NonNull
public String id;
#ColumnInfo(name = "name")
public String name;
#Ignore
public Tag(String name) {
this(UUID.randomUUID().toString(), name);
}
public Tag(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Notes Dao:
#Dao
public interface NoteDao {
#Query("SELECT * FROM notes ORDER BY id DESC")
LiveData<List<Note>> getAllNotes();
#Insert
long insert(Note note);
#Update
void update(Note note);
#Delete
void delete(Note note);
#Query("DELETE FROM notes")
void deleteAll();
#Query("SELECT COUNT(*) FROM notes")
int getNotesCount();
#Query("SELECT notes.* FROM notes\n" +
"INNER JOIN note_tag_join ON notes.id=note_tag_join.noteId\n" +
"WHERE note_tag_join.tagId=:tagId")
List<Note> getAllNotesOfTag(String tagId);
#Insert
void insert(Note.TagJoin... joins);
#Delete
void delete(Note.TagJoin... joins);
}
So far everything is good. Now I want to show the Notes in RecyclerView but I can't find a way to fetch all Notes along with Tags at once. One way is, getting the tags of each note in onBindViewHolder method which I think is wrong as we have to query the db each time row is displayed.
Please provide me suggestions.
PS: I have followed the code provided in this article
https://commonsware.com/AndroidArch/previews/mn-relations-in-room

Encapsulation in Java when returning an object

Consider below example:
public class sample{
private Map myMap;
public Map getMap(){
return myMap;
}
}
In above example, we are returning the map to some other calling class. So my question is how we can say that this class encapsulates/protects its data. The Map that will be returned will be available for modification by other classes.
Thanks,
Rajan
Consider this class Person, which have 2 attributes (name and age).
package app;
/**
*
* #author salathielgenese
*/
public final class Person
{
public Person()
{
setAge(age);
setName(name);
}
public Person(String name, long age)
{
setName(name);
setAge(age);
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public long getAge()
{
return age;
}
public void setAge(long age)
{
this.age = age;
}
private String name;
private long age;
}
Now imagine that some one (let say the calling class) set the age to -19. This will generate inconsistency in your that.
So when you protect your data, your controlling wich kind of action are made possible these data.
You may decide that if the given age is lower than 0 then the age will be set to 0 for example. The code may become...
public void setAge(long age)
{
this.age = age;
if (age < 0)
{
this.age = 0;
}
}
You can do the same with name attribute to prevent setting it to null.
public void setName(String name)
{
this.name = name;
if (name == null || name == "")
{
this.name = "NO NAME";
}
}
We'll say that encapsulation help protecting data.
··························································································
Now let's imagine a class called Carpenter. When you need a table, you just ask it to him. Thus the Carpenter class should provide a method which takes a description of the table you need, and return the build table. Assuming that the method is called buildTable, this method will be declared with public access because it's useful to call it from another Class.
When you ask to the Carpenter to build up your Table, he will need to check some material as well as saw, needle and so on and so far. We (calling class) don't care about this internal mechanism and all methods as well as attributes involved in this process will be declared with private access. i.e to prevents external classes from modifying them, i.e to encapsulate our fields and methods for better protection.
Encapsulating a field let us control access to our data.
Comming back to your code, giving public access to getMap() doesn't prevent calling class to modify its content.
Now look at this Example
Person.java
package app;
/**
*
* #author salathielgenese
*/
public final class Person
{
public Person()
{
setAge(age);
setName(name);
}
public Person(String name, long age)
{
setName(name);
setAge(age);
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
if (name == null || name == "")
{
this.name = "NO NAME";
}
}
public long getAge()
{
return age;
}
public void setAge(long age)
{
this.age = age;
if (age < 0)
{
this.age = 0;
}
}
#Override
public String toString()
{
return "Person{" + "name=" + name + ", age=" + age + '}';
}
private String name;
private long age;
}
Example.java
package app;
/**
*
* #author salathielgenese
*/
public class Example
{
public Example()
{
}
public Example(Person person)
{
this.person = person;
}
public Person getPerson()
{
return person;
}
public void setPerson(Person person)
{
this.person = person;
}
private Person person;
}
**Main class (Loader.java)
package app;
/**
*
* #author salathielgenese
*/
public class Loader
{
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
// Instantiate an Example with a new created Person
Example example = new Example(new Person("Rajan", 19));
// Retrive person in example and print its description (printing result of implicit call to person.toString() )
Person person = example.getPerson();
System.out.println(person);
// Assigning a new reference to the variable **person** and print its description
person = new Person("Salathiel", 20);
System.out.println(person);
// Print description of Person containning in Example instance
System.out.println(example.getPerson());
}
}
If you look closed this code, you'll understand that you can change attribute of your Map but not the reference to it.
Maybe you can use an unmodifiable map from Java Collection API's :
public class sample{
private Map myMap;
public Map getMap(){
return Collections.unmodifiableMap(myMap));
}
}

Resources