I want to create a ArrayList of data and return it via Rest point. I tried this:
#Service
public class CardBrandsListService {
public ArrayList<String> getCardBrandsList() {
ArrayList<String> list = new ArrayList<String>();
list.add("visa");
list.add("master");
list.add("Intl Maestro");
list.add("amex");
return list;
}
}
Rest endpoint:
#GetMapping("/card_brand/list")
public ResponseEntity<?> getCurruncy() {
return ResponseEntity.ok(cardBrandsListService.getCardBrandsList().entrySet().stream()
.map(g -> new CardBrandsListDTO(g.getValue())).collect(Collectors.toList()));
}
DTO:
public class CardBrandsListDTO {
private String card_brand;
public String getCard_brand() {
return card_brand;
}
public void setCard_brand(String card_brand) {
this.card_brand = card_brand;
}
}
But I get error: The method entrySet() is undefined for the type ArrayList<String> What is the proper wya to map ArrayList?
Your rest endpoint should look like the following:
#GetMapping("/card_brand/list")
public ResponseEntity<List<CardBrandsListDTO>> getCurruncy() {
return ResponseEntity.ok(cardBrandsListService.getCardBrandsList().stream()
.map(g -> new CardBrandsListDTO(g)).collect(Collectors.toList()));
You are calling entrySet(), which is used to get a Set of entries of a Map object (which you don't have). Additionally, inside the map function, your variable g is a String (since you are returning an ArrayList<String>), therefore you can directly supply that to the constructor. And you can directly set the correct type for the ResponseEntity as well.
UPDATE:
And you need the corresponding constructor:
public class CardBrandsListDTO {
private String card_brand;
public CarBrandsListDTO(String card_brand) {
this.car_brand = car_brand;
}
//getter and setter
}
By the way, I would advise you to rename the DTO (for understandability) and also the field inside it (to follow naming conventions)
Related
Is it possible to cast List Objects to List of Objects from Factory pattern?
I have a Jersey REST endpoint and I migrate data from one environment to another. I wish to post some list of Object and cast them to right object taken from factory pattern
#Path("/migrateTableAtOnce")
#Consumes(MediaType.APPLICATION_JSON)
public <T> Response saveObjectIntoDb(List<T> listOfObj) {
// if listOfObj.getTableName() == "MW_ID_GENERATOR" tableOject gets new MwIdGenerator()
myEntity tableObject = myEntityFactory.getTable(listOfObj.getTableName());
return Response.status(201).entity("ok").build();
}
Is it possible that I have only one post method which that generic List. I have 20 objects which I need to transfer and I dont want to write 20 post methods :( I dont know how to do it exactly.
One of my method looks like that:
#POST
#Path("/migrateTableAtOnceMwIdGenerator")
#Consumes(MediaType.APPLICATION_JSON)
public Response saveObjectIntoDb(List<MwIdGenerator> listOfObj) {
Boolean result = false;
String dbResponse ="";
try {
dbResponse = obtainFacade().saveToDb(listOfObj);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return Response.status(201).entity(result+" "+dbResponse).build();
}
Is there no better solution to solve this problem?
I post the body as a custom object, and have a list within that object like;
#POST
#Path("/migrateTableAtOnceMwIdGenerator")
#Consumes(MediaType.APPLICATION_JSON)
public Response saveObjectIntoDb(CustomObject object) {
List <Stuff>list = object.getList();
and the object
public class CustomObject extends Serializable {
public List <Stuff>sList = null;
public List <OtherStuff>osList = null;
public List <TheBestStuff>tbsList = null; //etcetc
public List getList ()
{
return list;
}
public void setList(List <Stuff>list)
{
this.list = list;
}
public List getOsList ()
{
return osList ;
}
public void setList(List <OtherStuff>osList)
{
this.osList = osList;
}
public List getTbsList ()
{
return tbsList;
}
public void setTbsList(List <TheBestStuff>tbsList)
{
this.tbsList = tbsList;
}
and Jersey can parse the json object into your custom object, provided that you can pass the fields of that class as json. Seeing as you're passing the data with json, you're limited as to your implimentation as json only covers String, int, boolean and simple date, but you can pass most values as String and then parse.
I am using google's AutoValue to generate some configs, but before generating the configs, I would like to make sure that the entries are sanitized and default values are added to the list.
The AutoValue part looks like:
#AutoValue.Builder
public abstract static class Builder {
public abstract Builder primaryName(List<String> value);
public abstract Optional<List<String>> primaryName();
public abstract Builder primaryTitle(List<String> value);
abstract Optional<List<String>> primaryTitle();
abstract Config autoBuild();
public Config build() {
normalizePriorities();
EntitySourcePrioritizationConfig config = autoBuild();
return config;
}
I have the following code that is repeated in normalizePriorities():
private void normalizePriorities()
{
normalizeName();
normalizeTitle();
}
private void normalizeName() {
if (!primaryName().isPresent()) {
primaryName(defaultPrimaryNames());
} else {
List<String> providedConfigEntries = primaryName().get();
List<String> cleanConfig = sanitizeConfig(providedConfigEntries);
primaryName(cleanConfig);
}
}
private void normalizeTitle() {
if (!primaryTitle().isPresent()) {
primaryTitle(defaultPrimaryTitles());
} else {
List<String> providedConfigEntries = primaryTitle().get();
List<String> cleanConfig = sanitizeConfig(providedConfigEntries);
primaryTitle(cleanConfig);
}
}
I was wondering how I could use lambda expressions in order to reduce the deduplication of code.
The default names and titles are just a list of Strings as follows that could be passed as parameters:
public static ImmutableList<String> defaultPrimaryTitles() {
return ImmutableList.of(
"BBA",
"TNN");
}
public static ImmutableList<String> defaultPrimaryNames() {
return ImmutableList.of(
"SNS Inc.",
"ABC Corp.");
}
I have tried to generify the function like so:
normalize(primaryAlias(), defaultPrimaryTitles());
private void normalize(Optional<List<String>> configList, List<String> defaultConfig){
...
}
Unfortunately, I am not too sure how to generify and pass public abstract Builder primaryTitle(List<String> value) into the method.
You could pass a Consumer that accepts a list of strings and calls the builder methods, e.g.:
Create the consumer and pass it to the normalize method:
Consumer<List<String>> builderConsumer = (x) -> Builder.primaryName(x);
normalize(primaryAlias(), defaultPrimaryTitles(), builderConsumer);
And the normalize method:
private void normalize(ImmutableList<String> configList, List<String> defaultConfig, Consumer<List<String>> builderConsumer) {
List<String> cleanConfig = new ArrayList<>();
// ...
builderConsumer.accept(cleanConfig);
}
I have a Switch that contains 13 case, each case executes a different sql request. I got the result in an ArrayList<HashMap<String, String>>. This result is supposed to be displayed with angular , for now i'm using this this.respTest = JSON.stringify(response); so it displays a list of "key":"value" .
My problem is since each request gets me different database fields and values ,so I want to merge some fields .
I created this class :
public class DataCollect {
private String type ;
private String entity ;
private String modPar ;
private String dateModif ;
private String numVersion ;
public DataCollect(String type, String entity, String modPar, String dateModif, String numVersion) {
this.type = type;
this.entity = entity;
this.modPar = modPar;
this.dateModif = dateModif;
this.numVersion = numVersion;
}
public DataCollect() {
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getEntity() {
return entity;
}
public void setEntity(String entity) {
this.entity = entity;
}
public String getModPar() {
return modPar;
}
public void setModPar(String modPar) {
this.modPar = modPar;
}
public String getDateModif() {
return dateModif;
}
public void setDateModif(String dateModif) {
this.dateModif = dateModif;
}
public String getNumVersion() {
return numVersion;
}
public void setNumVersion(String numVersion) {
this.numVersion = numVersion;
} }
In this class I'm supposed to affect the fields' names to the variables that I created and as a return an arraylist of hashmap with the data I extracted from the data base.
I mean I used to return for example "field-name":"value" , I want to return "type":"value","entity":"value" ..etc
I'm using springboot for the backend and angular 5 for the front.
Any help would be appreciated.
What you essentially want is a way to map keys in [each of] your hashmap to the corresponding member variable in the "DataCollect" POJO.
If there is a one to one mapping between the key present and corresponding member variable, you can expose a public constructor in "DataCollect" that takes in the hash map and constructs the corresponding object.
public DataCollect(Map<String, String> result) {
this.type = result.get("type");
this.entity = result.get("db_entity_key");
...
}
If there is no one on one mapping, you'd have to create a factory class, which takes your Map as an input and some context, and returns you the constructed DataCollect object.
Once you have the constructor or the factory class, you only need to iterate over your results list and do the needful to convert each Map into the DataCollect object.
Your controller should automatically serialise the DataCollect objects to corresponding JSON, or you can even use Jackson's ObjectMapper to achieve the same.
Edit: I was trying to simplify my problem at hand a little, but turns out, it created more confusion instead. Here's the real deal:
I am working with AWS's Java SDK for DynamoDB. Using the DynamoDBMapper class, I am trying to query DynamoDB to retrieve items from a particular table. I have several objects that map to my DynamoDB tables, and I was hoping to have a generic method that could accept the mapped objects, query the table, and return the item result.
Psudo-code:
#DynamoDBTable(tableName="testTable")
public class DBObject {
private String hashKey;
private String attribute1;
#DynamoDBHashKey(attributeName="hashKey")
public String getHashKey() { return this.hashKey; }
public void setHashKey(String hashKey)
#DynamoDBAttribute(attributeName="attribute1")
public String getAttribute1() { return this.attribute1; }
public void setAttribute1(String attribute1) { this.attribute1 = attribute1; }
}
public class DatabaseRetrieval {
public DatabaseRetrieval()
{
DBObject dbObject = new DBObject();
dbObject.setHashKey = "12345";
DBRetrievalAgent agent = new DBRetrievalAgent;
dbObject = agent.retrieveDBObject(dbObject.getClass(), dbObject);
}
}
public class DBRetrievalAgent {
public Object retrieveDBObject(Class<?> classType, Object dbObject)
{
DynamoDBQueryExpression<classType> temp = new DynamoDBQueryExpression<classType>().withHashKeyValues(dbObject);
return this.dynamoDBMapper.query(classType, temp);
}
}
Use a type witness within your method:
public <T> String getResult(Class<T> type) {
List<T> newList = new ArrayList<>();
//other code
}
Try this
ArrayList<T> newList = new ArrayList<>();
You can specify the type as T for your getResult() to make it generic (i.e., accepts any class) as shown below:
public <T> String getResult(T t) {
String result = "";
List<T> newList = new ArrayList<>();
// perform actions
return result;
}
I would like to use functional programming to copy data from a collection of one object to a collection of other objects.
I have been reading several Java 8 books and researching online. I am pretty sure I want to use stream(), but just about every example I have seen always iterates through a collection, does some processing on the objects in the collection, and uses println() to output the contents. No one seems to discuss how to deal with situations like the one described below.
Suppose we have the following objects:
public class ObjectA
{
private String someData;
private int moreData;
public String getSomeData()
{
return someData;
}
public void setSomeData(String sData)
{
someData = sData;
}
public int getMoreData()
{
return moreData;
}
public void setMoreData(int mData)
{
moreData = mData;
}
}
public class ObjectB
{
private String b_Data;
public String getB_Data()
{
return b_Data;
}
public void setB_Data(String bData)
{
b_Data = bData;
}
}
I want to create a collection of ObjectB objects whose b_data atributes are equal to the someData attributes in a collection of ObjectAs.
A reasonably good way to do this is illustrated in the code below:
public class Collector
{
public Collection<ObjectB> collectObjects(Collection<ObjectA> theAs)
{
// The use of an ArrayList is arbitrary. I might want to use any number
// of different lists or even different collections!
final Collection<ObjectB> theBs = new ArrayList<ObjectB>();
for(ObjectA obj : theAs)
{
final ObjectB bobj = new ObjectB();
bobj.setB_Data(obj.getSomeData());
theBs.add(bobj);
}
return theBs;
}
}
The code in the collectObjects() method will work, but it uses techniqhes of imperative programming. I would like to know how to make the collection of ObjectBs using functional techniques.
Is there a way to accomplish this using streams and lambdas?
This situation actually applies perfectly with the Stream API. What you want is to:
Make a Stream<ObjectA> which is a Stream of your input list, with theAs.stream().
Map each ObjectA in the Stream to an ObjectB with Stream.map.
Collect the result with Stream.collect into a new list using Collectors.toList().
This would be an implementation:
public Collection<ObjectB> collectObjects(Collection<ObjectA> theAs) {
return theAs.stream().map(obj -> {
final ObjectB bobj = new ObjectB();
bobj.setB_Data(obj.getSomeData());
return bobj;
}).collect(Collectors.toList());
}
Of course, you could create a constructor of ObjectB that takes obj.getSomeData() as parameter. It would simplify the code because then you could write:
public Collection<ObjectB> collectObjects(Collection<ObjectA> theAs) {
return theAs.stream().map(obj -> new ObjectB(obj.getSomeData())).collect(Collectors.toList());
}
obj -> new ObjectB(obj.getSomeData()) is called a lambda expression.
You can do it like this:
List<ObjectB> theBs = theAs
.stream()
.map(a-> {
final ObjectB bobj = new ObjectB();
bobj.setB_Data(a.getSomeData());
return bobj;
}).collect(Collectors.toList());
The a -> { ... } construct is a lambda, a construct that lets you pass some executable code into a method call.
The body of the lambda comes straight from the loop body in your second example.