In Picocli, is it possible to pair parameters of an arbitrary length? For example:
grades Abby 4.0 Billy 3.5 Caily 3.5 Danny 4.0
where each pair must have a name and a grade but the total length is unknown, i.e.:
grades <name> <grade> [<name> <grade>]*
A parameter map is the closest that appears might work, e.g.
#Parameters(index = "0..*") Map<String, float> grades;
would parse:
grades Abby=4.0 Billy=3.5 Caily=3.5 Danny=4.0
into the map but it'd be nicer if the equals wasn't there...
Update: picocli 4.3 has been released with improved support for positional parameters in argument groups.
#Command(name = "grades", mixinStandardHelpOptions = true, version = "grades 1.0")
public class Grades implements Runnable {
static class StudentGrade {
#Parameters(index = "0") String name;
#Parameters(index = "1") BigDecimal grade;
}
#ArgGroup(exclusive = false, multiplicity = "1..*")
List<StudentGrade> gradeList;
#Override
public void run() {
gradeList.forEach(e -> System.out.println(e.name + ": " + e.grade));
}
public static void main(String[] args) {
System.exit(new CommandLine(new Grades()).execute(args));
}
}
Running the above program with this input:
Alice 3.5 Betty 4.0 "X Æ A-12" 3.5 Zaphod 3.4
Produces the following output:
Alice: 3.5
Betty: 4.0
X Æ A-12: 3.5
Zaphod: 3.4
Prior to picocli 4.3, applications can do the following to accomplish this:
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Parameters;
import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
#Command(name = "grades", mixinStandardHelpOptions = true, version = "grades 1.0")
public class Grades implements Runnable {
#Parameters(arity = "2",
description = "Each pair must have a name and a grade.",
paramLabel = "(NAME GRADE)...", hideParamSyntax = true)
List<String> gradeList;
#Override
public void run() {
System.out.println(gradeList);
Map<String, BigDecimal> map = new LinkedHashMap<>();
for (int i = 0; i < gradeList.size(); i += 2) {
map.put(gradeList.get(i), new BigDecimal(gradeList.get(i + 1)));
}
}
public static void main(String[] args) {
int exitCode = new CommandLine(new Grades()).execute(args);
System.exit(exitCode);
}
}
Related
java.lang.IllegalStateException: No primary or single unique constructor found for class java.lang.Long
2023-01-28 18:19:08.735 ERROR 7152 --- [nio-8080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: No primary or single unique constructor found for class java.lang.Long] with root cause
package com.example.prescription.model;
import javax.persistence.*;
import java.io.Serializable;
import java.util.*;
#SuppressWarnings("ALL")
#Entity
#Table(name="drugs")
public class Drug implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name="name")
private String drugName;
#Column(name="description")
private String description;
#Column(name = "dosage")
private String dosage;
#Column(name = "side_effects")
private String side_effects;
#Temporal(TemporalType.TIMESTAMP)
private Date createdAt;
#ManyToMany(mappedBy = "drugs",cascade = CascadeType.ALL)
private Set<Patient> patients = new HashSet<>();
public Drug() {
}
public Drug(String drugName) {
this.drugName = drugName;
}
public Drug(Long id, String drugName, String description, String dosage, String side_effects, Date createdAt) {
this.id = id;
this.drugName = drugName;
this.description = description;
this.dosage = dosage;
this.side_effects = side_effects;
this.createdAt = createdAt;
}
public Drug(Patient patient, Drug drug, Date date) {
}
//GETTERS SETTERS
}
package com.example.prescription.model;
import javax.persistence.*;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.Date;
import java.util.Iterator;
import java.util.Objects;
import java.util.Set;
#Entity
#Table(name = "patients")
public class Patient implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "dob")
private String dateOfBirth;
#NotEmpty(message = "Phone number may not be empty")
#Size(min = 10, max = 10)
#Column(name = "phone")
private String phone;
#NotEmpty(message = "Email may not be empty")
#Size(min = 7, max = 50)
#Column(name = "email")
private String email;
#Column(name = "fathers_name")
private String fathersName;
#Column(name = "mothers_name")
private String mothersName;
#Column(name = "amka")
#Size(min = 11, max = 11)
#Pattern(regexp = "^[0-9]+$", message = "AMKA must contain only numbers")
private String amka;
#Column(name = "id_card")
#Pattern(regexp = "^[a-zA-Z0-9]+$", message = "ID must contain only letters and numbers")
private String idCard;
#Column(name = "city")
private String city;
#Column(name = "postal_code")
#Size(min = 5, max = 5)
#Pattern(regexp = "^[0-9]+$", message = "PC must contain only numbers")
private String postalCode;
#Column(name = "symptoms")
private String symptoms;
#Column(name = "pharmacy")
private String pharmacy;
#Column(name = "doctor_name")
private String doctorsName;
#Column(name = "message")
private String message;
#ManyToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE})
#JoinTable(name = "patient_drug",joinColumns = #JoinColumn(name = "patient_id"),
inverseJoinColumns = #JoinColumn(name = "drug_id"))
private Set<Drug> drugs;
public Patient(Patient patient, Drug drug, Date date) {
}
public Patient() {
}
GETTERS SETTERS
public void addDrug(Drug drug){
this.drugs.add(drug);
drug.getPatients().add(this);
}
public void removeDrug(Drug drug) {
this.drugs.remove(drug);
drug.getPatients().remove(this);
}
public void removeDrugs() {
Iterator<Drug> iterator = this.drugs.iterator();
while (iterator.hasNext()) {
Drug drug = iterator.next();
drug.getPatients().remove(this);
iterator.remove();
}
}
}
package com.example.prescription.controller;
import com.example.prescription.model.Drug;
import com.example.prescription.model.Patient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import com.example.prescription.service.DrugService;
import com.example.prescription.service.PatientService;
import javax.activation.MimeType;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;
#Controller
public class PatientController {
private final PatientService patientService;
private final DrugService drugService;
public PatientController(#Autowired PatientService patientService,
#Autowired DrugService drugService) {
this.patientService = patientService;
this.drugService = drugService;
}
}
#GetMapping("/prescribeDrugs/{id}")
public ModelAndView prescribeDrugs(#PathVariable("id") String id) {
Long pid = Long.parseLong(id);
ModelAndView mav = new ModelAndView("patientFormEdit");
Patient formPatient = patientService.findPatientById(pid);
mav.addObject("patient", formPatient);
mav.addObject("drugs", drugService.getAllDrugs());
return mav;
}
protected Map referenceData(HttpServletRequest request) throws Exception {
Map referenceData = new HashMap();
Map<String,String> drug = new LinkedHashMap<String,String>();
drug .put("DP", "DEPON");
drug .put("AS", "ASPIRIN");
drug .put("PN", "PANADOL");
referenceData.put("drugList", drug );
return referenceData;
}
#PostMapping("/prescribeDrugs/Patient/{id}")
public String prescribePatientDrugs(#Valid Patient patient, String id, #ModelAttribute(value = "drugs") Long drugId, BindingResult result, MimeType request) {
if (result.hasErrors()) {
return "patients";
}
try {
Long pId = Long.parseLong(request.getParameter("pId"));
Patient formPatient = patientService.findPatientById(pId);
Drug drug = drugService.findById(drugId);
formPatient.setCity(patient.getCity());
formPatient.setEmail(patient.getEmail());
formPatient.setPhone(patient.getPhone());
formPatient.setSymptoms(patient.getSymptoms());
formPatient.setPharmacy(patient.getPharmacy());
formPatient.setDoctorsName(patient.getDoctorsName());
formPatient.setMessage(patient.getMessage());
Drug patientDrug = new Drug(patient, drug, new Date());
drugService.save(drug);
formPatient.getDrugs().add(patientDrug);
patientService.updatePatient(formPatient);
} catch (NumberFormatException n) {
System.out.println("error");
}
return "redirect:/allPatients";
}
}
<form th:action="#{/prescribeDrugs/Patient/{id}(id = ${patient.id})}" method="post" th:object="${patient}">
<div class="container prescription-form">
<div class="row">
<div class="col-lg-12 col-12">
<form>
<h1>Electronic Prescription Form</h1>
<div class="row">
<div class="col-lg-6 col-12">
<label>
<span>Patient Name</span><input type="text" th:value="${patient.firstName}"
th:name="firstName" disabled/>
</label>
</div>
<span class="error_message">This field is required</span>
</div>
<form:select path="drug" items="${drugList}" />
<select id="drug" name="drug">
<option value="AS">ASPIRIN</option>
<option value="DE">DEPON</option>
<option value="PN">PANADOL</option>
</select>
I have a Model that accepts a row number, column, and its value. I want to populate a table view where the value of the column is pointing to the value in the Model on the current column. (Not a native English speaker, so sorry).
Here is what I have so far
public class DynamicTableView extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
ObservableList<TableData> observableList= FXCollections.observableArrayList(
new TableData(1, 1, 123.00),
new TableData(1, 2, 124.00),
new TableData(1, 3, 125.00),
new TableData(2, 1, 126.00),
new TableData(2, 2, 127.00),
new TableData(2, 3, 128.00),
new TableData(3, 1, 129.00),
new TableData(3, 2, 130.00),
new TableData(3, 3, 131.19)
);
TableView<TableData> tableView = new TableView<>(observableList);
//Creating columns
TableColumn<TableData, Short> colRow = new TableColumn<>("Row");
TableColumn<TableData, Double> colCol1 = new TableColumn<>("Column 1");
TableColumn<TableData, Double> colCol2 = new TableColumn<>("Column 2");
TableColumn<TableData, Double> colCol3 = new TableColumn<>("Column 3");
//Set the value
colRow.setCellValueFactory(new PropertyValueFactory<>("rowNumber"));
/* colCol1.setCellValueFactory(new PropertyValueFactory<>("value"));
colCol2.setCellValueFactory(new PropertyValueFactory<>("value"));
colCol3.setCellValueFactory(new PropertyValueFactory<>("value")); */
//add columns to table
tableView.getColumns().addAll(colRow, colCol1, colCol2, colCol3);
JFXButton button = new JFXButton("Add Data");
button.setOnAction (e-> {
observableList.add(new TableData(5, 1, 132.20));
});
VBox root = new VBox(10, button, tableView);
root.setAlignment(Pos.CENTER);
primaryStage.setScene(new Scene(root, 500, 300));
primaryStage.show();
}
public class TableData {
SimpleIntegerProperty rowNumber;
SimpleIntegerProperty columnNumber;
SimpleDoubleProperty value;
public TableData(int row, int col, double val) {
this.rowNumber = new SimpleIntegerProperty(row);
this.columnNumber = new SimpleIntegerProperty(col);
this.value = new SimpleDoubleProperty(val);
}
}
}
Expected Output
+-----+--------+--------+--------+
| Row | Col 1 | Col 2 | Col 3 |
+-----+--------+--------+--------+
| 1 | 123.00 | 124.00 | 125.00 |
+-----+--------+--------+--------+
| 2 | 126.00 | 127.00 | 128.00 |
+-----+--------+--------+--------+
| 3 | 129.00 | 130.00 | 131.19 |
+-----+--------+--------+--------+
I have seen this example https://stackoverflow.com/a/27497094/14660358, but I could hardly follow and implement it to my problem.
The only solution I have so far was to reconstruct my model to something like this :
public class TableData {
SimpleIntegerProperty rowNumber;
SimpleDoubleProperty column1;
SimpleDoubleProperty column2;
SimpleDoubleProperty column3;
public TableData(int row, double col1, double col2, double col3) {
this.rowNumber = new SimpleIntegerProperty(row);
this.column1 = new SimpleDoubleProperty(col1);
this.column2 = new SimpleDoubleProperty(col2);
this.column3 = new SimpleDoubleProperty(col3);
}
}
Then populate the table's column value property to
colCol1.setCellValueFactory(new PropertyValueFactory<>("column1"));
But I knew this is not a good programming practice. So I was hoping for someone to give atleast a much more detailed example if possible :)
PS: I'm still working on the question's title, so sorry if this misleads someone.
I need to summarize a column of a state. I created a mappedSchema and defined the field as Double.
If I list the states, the values for that field are correct. But if I use builder::sum(), the value returns with rounding problems and more decimal places than it should.
Here are excerpts from the code:
STATE
data class ConsumerMeteringState(val metering : ConsumerMetering,
val meteringParticipants : List<AbstractParty> = listOf(),
override val linearId: UniqueIdentifier = UniqueIdentifier()) :
LinearState, QueryableState {
override val participants: List<AbstractParty> = meteringParticipants
override fun generateMappedObject(schema: MappedSchema): PersistentState {
return when (schema) {
is ConsumerMeteringSchemaV1 -> ConsumerMeteringSchemaV1.PersistentConsumerMetering(
this.metering.dateTimeIni,
this.metering.dateTimeEnd,
this.metering.quantityKwh,
this.linearId.id
)
else -> throw IllegalArgumentException("Unrecognised schema $schema")
}
}
override fun supportedSchemas(): Iterable<MappedSchema> = listOf(ConsumerMeteringSchemaV1)
SCHEMA
object ConsumerMeteringSchemaV1 : MappedSchema(
schemaFamily = ConsumerMeteringSchema.javaClass,
version = 1,
mappedTypes = listOf(PersistentConsumerMetering::class.java)) {
#Entity
#Table(name = "consumer_metering_states")
class PersistentConsumerMetering(
#Column(name = "date_time_ini")
var dateTimeIni: Instant,
#Column(name = "date_time_end")
var dateTimeEnd: Instant,
#Column(name = "quantity_kwh")
var quantityKwh: Double,
#Column(name = "linear_id")
var linearId: UUID
) : PersistentState() {
// Default constructor required by hibernate.
constructor(): this(Instant.now(), Instant.now(), 0.0, UUID.randomUUID())
}
}
VAULTQUERY CRITERIA
val criteriaAccount = QueryCriteria.VaultQueryCriteria(externalIds = listOf(accountId))
val sumQuantityKwh = builder { ConsumerMeteringSchemaV1
.PersistentConsumerMetering::quantityKwh.sum() }
val sumQuantityKwhCriteria = QueryCriteria.VaultCustomQueryCriteria(sumQuantityKwh)
serviceHub.vaultService.queryBy(contractStateType = ConsumerMeteringState::class.java,
criteria = criteriaAccount.and(sumQuantityKwhCriteria)).otherResults.singleOrNull()
States only (the values are OK):
[ConsumerMeteringState(metering=ConsumerMetering(dateTimeIni=2020-06-03T09:46:00Z, dateTimeEnd=2020-06-03T09:59:00Z, quantityKwh=10.55), meteringParticipants=[Anonymous(DL624i3ieTdLkPRBUvUgZnzn5jeG3Md2cvANt6sZNJiXwy), O=Distributor, L=Curitiba, C=BR], linearId=2e5009ad-56c3-4fed-ba36-deb0d48e668c), ConsumerMeteringState(metering=ConsumerMetering(dateTimeIni=2020-06-03T09:46:00Z, dateTimeEnd=2020-06-03T09:59:00Z, quantityKwh=50.18), meteringParticipants=[Anonymous(DLBep6kdDduaMKVrszQWa7N8i6YNnJLtA4WXsp4QmZiEjC), O=Distributor, L=Curitiba, C=BR], linearId=3b012984-676d-4e62-9b9f-1bb8158aaf4b)]
With builder sum:
I get the value 60.730000000000004
Why sum doesn't return 60.73 ?
It worked by changing the column type from Double to BigDecimal. It seems to be some question of precision of the Double type.
I did a test just by retrieving the states and making a simple sum of the quantityKwh (Double) field and the precision was already strange.
I didn't understand the reason for this behavior, but with BigDecimal it worked ok.
So im developing an app and I want the user to search for a food item in my database and then to be returned with a list view of all food names that match the search criteria. I already have my slqite database created and added to the assets folder. The database is called foodDatabase.db
I have created the Database Helper like so:
package com.example.codebind.databasedemo;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by tom on 15/03/2018.
*/
public class FoodDatabaseHelper extends SQLiteOpenHelper{
public static final String DATABASE_NAME = "FoodDatabase.db";
public static final String TABLE_NAME = "dataset";
public static final String COL_1 = "ID";
public static final String COL_2 = "Food";
public static final String COL_3 = "Description";
public static final String COL_4 = "Protein";
public static final String COL_5 = "Fat";
public static final String COL_6 = "Carbohydrate";
public static final String COL_7 = "Energy";
public static final String COL_8 = "Starch";
public static final String COL_9 = "Sugar";
public static final String COL_10 = "Cholesterol";
public FoodDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL("create table " + TABLE_NAME +" (ID INTEGER
PRIMARY KEY AUTOINCREMENT,FOOD TEXT,DESCRIPTION TEXT,PROTEIN BLOB,FAT
BLOB,CARBOHYDRATE BLOB,ENERGY BLOB,STARCH BLOB,SUGAR BLOB,CHOLESTEROL BLOB)
");
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " +TABLE_NAME);
onCreate(sqLiteDatabase);
}
}
and currently my MainActivity.java is clean. I haven't touched it yet.
I'm asking for guidance on how to add a listener so that when the user enters a food name the app will return all foods from the foodDatabase.db that meets the search query.
Thanks
The basis of your search will be a query based upon the FOOD column (I believe).
e.g. SELECT * FROM dataset WHERE FOOD LIKE '%your_food%'
For example assume that your database has data such as (note only food and id columns have been populated with data) :-
Then the query SELECT * FROM dataset WHERE FOOD LIKE '%mash%' would result in :-
i.e. Foods with an id of 2 and 3 contain the food mash
You could run this query using the SQLiteDatabase query method. The query method returns a Cursor with the extracted data. So a method in your DatabaseHelper could be :-
public Cursor getFoodsWithProvidedFood(String provided_food) {
return this.getWritableDatabase().query(
TABLE_NAME,
null,
COL_2 + " LIKE '%" + provided_food + "%' ",
null,
null,
null,
null
);
}
Converting this into a complete but very basic App you could have :-
The Database Helper - FoodDatabaseHelper.java
public class FoodDatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "FoodDatabase.db";
public static final String TABLE_NAME = "dataset";
public static final String COL_1 = "ID";
public static final String COL_2 = "Food";
public static final String COL_3 = "Description";
public static final String COL_4 = "Protein";
public static final String COL_5 = "Fat";
public static final String COL_6 = "Carbohydrate";
public static final String COL_7 = "Energy";
public static final String COL_8 = "Starch";
public static final String COL_9 = "Sugar";
public static final String COL_10 = "Cholesterol";
SQLiteDatabase sqLiteDatabase; //<<<< Added
public FoodDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
sqLiteDatabase = this.getWritableDatabase(); //<<<< Amended
}
//#Override
public void onNotRecommendedCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL("create table " + TABLE_NAME +
" (ID INTEGER PRIMARY KEY AUTOINCREMENT," +
"FOOD TEXT," +
"DESCRIPTION TEXT," +
"PROTEIN BLOB," +
"FAT BLOB," +
"CARBOHYDRATE BLOB," +
"ENERGY BLOB," +
"STARCH BLOB," +
"SUGAR BLOB," +
"CHOLESTEROL BLOB)");
}
#Override
public void onCreate(SQLiteDatabase db) {
String crtsql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME +
"(" +
COL_1 + " INTEGER PRIMARY KEY, " +
COL_2 + " TEXT, " +
COL_3 + " TEXT, " +
COL_4 + " BLOB, " +
COL_5 + " BLOB, " +
COL_6 + " BLOB, " +
COL_7 + " BLOB, " +
COL_8 + " BLOB, " +
COL_9 + " BLOB, " +
COL_10 + " BLOB " +
")";
db.execSQL(crtsql);
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " +TABLE_NAME);
onCreate(sqLiteDatabase);
}
public void insertFood(
String food,
String description,
byte[] protien,
byte[] fat,
byte[] carbohydrate,
byte[] energy,
byte[] starch,
byte[] sugar,
byte[] cholesterol) {
ContentValues cv = new ContentValues();
cv.put(COL_2,food);
cv.put(COL_3,description);
cv.put(COL_4,protien);
cv.put(COL_5,fat);
cv.put(COL_6,carbohydrate);
cv.put(COL_7,energy);
cv.put(COL_8,starch);
cv.put(COL_9,sugar);
cv.put(COL_10,cholesterol);
SQLiteDatabase db = this.getWritableDatabase();
db.insert(TABLE_NAME,null,cv);
}
public Cursor getFoodsWithProvidedFood(String provided_food) {
return this.getWritableDatabase().query(
TABLE_NAME,
null,
COL_2 + " LIKE '%" + provided_food + "%' ",
null,
null,
null,
null
);
}
}
Notes
It will likely cause fewer issue if you have just one place where you define table and column names.
hence the changed onCreate
although column names in SQLite are case-insensitive the Cursor's getColumnIndex method (as used in the main activity) is case-sensitive (IMO a bug).
AUTOINCREMENT doesn't do what it implies, rather INTEGER PRIMARY KEY itself makes a column one that increments adding AUTOINCREMENT is a special case that ensures that the id is greater at the expense of overheads. Hence AUTOINCREMENT has been removed.
Two additional methods have been added
insertFood to insert(add) data to the dataset table.
getFoodsWithProvidedFood as described above.
The Activity - MainActivity.java
public class MainActivity extends AppCompatActivity {
FoodDatabaseHelper foodDBHlpr;
Cursor mCsr;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
foodDBHlpr = new FoodDatabaseHelper(this);
byte[] dummy = new byte[]{0,1,2,3,4,5,6,7,8,9};
// Add some data oif none exists
if (DatabaseUtils.queryNumEntries(foodDBHlpr.getWritableDatabase(),FoodDatabaseHelper.TABLE_NAME) < 1) {
foodDBHlpr.insertFood("Fish and Chips", "The English Seaside meal",
dummy, dummy, dummy, dummy, dummy, dummy, dummy);
foodDBHlpr.insertFood("Bangers and Mash", "Yummy!!",
dummy, dummy, dummy, dummy, dummy, dummy, dummy);
foodDBHlpr.insertFood("Mashed Potatoe", "Boring",
dummy, dummy, dummy, dummy, dummy, dummy, dummy);
}
// get a Cursor with the extracted foods
mCsr = foodDBHlpr.getFoodsWithProvidedFood("Mash");
// Loop Through the Cursor
while (mCsr.moveToNext()) {
Log.d("FOODFOUND","You found the food called - " + mCsr.getString(mCsr.getColumnIndex(FoodDatabaseHelper.COL_2)));
}
if (mCsr.getCount() < 1) {
Log.d("FOODFOUND","No foods found that match the search criteria.");
}
mCsr.close(); //<<<< Should always close Cursors when done with them
}
}
Result in the Log :-
03-15 21:48:21.170 1702-1702/foodsdb.so49307874_foodsdb D/FOODFOUND: You found the food called - Bangers and Mash
03-15 21:48:21.170 1702-1702/foodsdb.so49307874_foodsdb D/FOODFOUND: You found the food called - Mashed Potatoe
Given a dictionary of a directed graph, representing nested groups and their members, return all the users for a given group.
example-
Hashmap-
key|Values
Group1- [ Group3, Group5, User8, User2]
Group2 -[ Group1, User9]
Group3 -[ Group4, User5]
Group4 -[ User1, User3]
Group5 -[ User4, User7]
O/P should be :
group1 : [User1, User3,User5, User4, User7,User8, User2]
group2 : [User1, User3,User5, User6, User7,User8, User9]
group3: [User1, User3,User5]
group4: [User1, User3]
group5: [User4, User7]
I have tried in various way for example a recursive function, but I just ended scratching my head.
public static void main(String[] args) {
HashMap<String, List<String>> hmap = new HashMap<String,List<String>>();
List<String> l1 = new ArrayList<String>();
List<String> l2 = new ArrayList<String>();
List<String> l3 = new ArrayList<String>();
List<String> l4 = new ArrayList<String>();
List<String> l5 = new ArrayList<String>();
l1.add("group3"); l1.add("group5"); l1.add("user8"); l1.add("user2");
l2.add("group1"); l2.add("user9");
l3.add("group4"); l3.add("user5");
l4.add("user1"); l4.add("user3");
l5.add("user4"); l5.add("user9");
hmap.put("group1",l1);
hmap.put("group2",l2);
hmap.put("group3",l3);
hmap.put("group4",l4);
System.out.println(hmap);
flatten(hmap);
}
public static void flatten(HashMap<String, List<String>> hmap){
ArrayList<String> groups = new ArrayList<String>();
for(Entry<String,List<String>> entryset : hmap.entrySet()){
groups.add(entryset.getKey());
}
System.out.println(groups);
for(Entry<String,List<String>> entryset : hmap.entrySet()){
String s1 = entryset.getKey();
//HashSet<String> set1 = new HashSet<String>();
ArrayList<String> values = new ArrayList<String>();
values.addAll(entryset.getValue());
}
Here is one way to do it using Scala:
def run(): Unit =
{
/* Simply initializing the given data into User and Group classes */
val (u1, u2, u3, u4) = (new User("u1"), new User("u2"), new User("u3"), new User("u4"))
val (u5, u6, u7, u8, u9) = (new User("u5"), new User("u6"), new User("u7"), new User("u8"), new User("u9"))
val g5 = new Group(List(u4, u7))
val g4 = new Group(List(u1, u3))
val g3 = new Group(List(g4, u5))
val g1 = new Group(List(g3, g5, u8, u2))
val g2 = new Group(List(g1, u9))
/* Put the groups into a list */
var groups = List(g1, g2, g3, g4, g5)
/* Map/loop over each group, calling `resolveItems` on each */
groups = groups.map{_.resolveItems}
/* Print out each of the resolved groups */
groups.foreach{println}
}
/* A simple class representing the Group entity */
case class Group(var items: List[Any])
{
/*
Returns a new group by recursively resolving the items
in this group into only users
*/
def resolveItems: Group =
{
new Group(this.items.map{
// If the item is a group, resolve it into users
case g: Group => g.resolveItems
// If the item is a user, just move along
case u: User => u
}.distinct)
}
/* Override to string for pretty printing */
override
def toString: String = items.mkString(", ")
}
/* Simply class representing the user entity */
case class User(val name: String)
{
override
def toString : String = name
}
Output:
u1, u3, u5, u4, u7, u8, u2
u1, u3, u5, u4, u7, u8, u2, u9
u1, u3, u5
u1, u3
u4, u7