I have the method getPlan and I try to modify an object (attribute in my class)
class XYZ
/**
* Plan.
*/
private Plan plan;
#Override
public final Plan getPlan() {
subjects.addAll(plan.getSubjects());
...
return new Plan("1", subjects.size(), subjects);
}
#Override
public final Graph createGraph() {
Plan fPlan = getPlan();
...
return graph;
}
In the second method createGraph, I try to get the modified object (fPlan), but it's in the initial state (Plan plan). I hope you understand the situation.
Thanks in advance!
Either your method should not return a Plan, because Plan plan is an instance variable already. Plus you don't instantiate Plan plan anyway, so I guess you have to pick one of below pieces of code:
First piece: we make Plan plan an instance variable, and edit, modify and use that and only that. That means in this class, we don't have to return an Plans, as we have access to Plan plan in this instance of xyz.
class XYZ
private Plan plan;
#Override
public final void instantiatePlan() {
subjects.addAll(plan.getSubjects());
...
plan = new Plan("1", subjects.size(), subjects);
}
#Override
public final Graph createGraph() {
plan = instantiatePlan();
...
return graph;
}
second option: we remove the instance variable Plan plan, and in createGraph(), we call getPlan() with returns a Plan which we can modify and edit there. According to what I guess your context is, I'd go for the first option though.
class XYZ
#Override
public final Plan getPlan() {
subjects.addAll(plan.getSubjects());
...
return new Plan("1", subjects.size(), subjects);
}
#Override
public final Graph createGraph() {
Plan fPlan = getPlan();
...
//edit fPlan here.
return graph;
}
EDIT: Seeing your comment, I understand even less of your problem. First of all, in getPlan() you call getSubjects() on Plan plan, but it's not even instantiated, so it'll throw an NPE immediately. Second: let a method do what the name tells you: thus, getPlan() should just be return plan;, no more, no less, no editing, modifying in that method. I'd suggest making a constructor of class XYZ with params Plan plan:
public XYZ(Plan mPlan) {
this.plan = mPlan;
}
Or initializing it in the constructor:
public XYZ(ArrayList<Subject> subjects) {
this.plan = new Plan("1", subjects.size(), subjects);
}
Please tell where you want plan to be what.
Related
I am creating my web page with vaadin where I need to create same kind of blocks for different type for example need to show blocks having car details, so only car name would be different but the block design would be same with same label but different labels. I want to write generic code so that i can expand it for any car name, without adding it manually.
Attaching the code snippet which i am using where i am repeating my code for different type. Want to implement it dynamically.
private Grid<PresentableGenerateInputHeaders> winTSHeaderColumnsGrid;
private Grid<PresentableGenerateInputHeaders> fRHeaderColumnsGrid;
private ListDataProvider<PresentableGenerateInputHeaders> listDataProvider;
private List<PresentableGenerateInputHeaders> presentableGenerateInputHeaders = new ArrayList<>();
private void initWinTsGrid() {
listDataProvider = new ListDataProvider<>(presentableGenerateInputHeaders);
winTSHeaderColumnsGrid = new Grid<PresentableGenerateInputHeaders>(PresentableGenerateInputHeaders.class);
winTSHeaderColumnsGrid.setDataProvider(listDataProvider);
winTSHeaderColumnsGrid.setCaption(i18n.get("view.ruleDetails.general.csvHeaderColumns"));
winTSHeaderColumnsGrid.setStyleName("a-units");
winTSHeaderColumnsGrid.setWidth("450px");
winTSHeaderColumnsGrid.setItems(addGridValues(DataSource.WIN_TS, winTSHeaderColumnsGrid));
winTSHeaderColumnsGrid.getEditor().setEnabled(true);
winTSHeaderColumnsGrid.setColumnOrder("header", "count");
winTSHeaderColumnsGrid.sort("header");
winTSHeaderColumnsGrid.getEditor().addSaveListener((EditorSaveEvent<PresentableGenerateInputHeaders> event) -> {
event.getGrid().select(event.getBean());
selectedGapFillingCountWINTS.add(event.getBean());
});
}
private void initFRGrid() {
listDataProvider = new ListDataProvider<>(presentableGenerateInputHeaders);
fRHeaderColumnsGrid = new Grid<PresentableGenerateInputHeaders>(PresentableGenerateInputHeaders.class);
fRHeaderColumnsGrid.setDataProvider(listDataProvider);
fRHeaderColumnsGrid.setCaption(i18n.get("view.ruleDetails.general.csvHeaderColumns"));
fRHeaderColumnsGrid.setStyleName("a-units");
fRHeaderColumnsGrid.setWidth("450px");
fRHeaderColumnsGrid.setItems(addGridValues(DataSource.FR, fRHeaderColumnsGrid));
fRHeaderColumnsGrid.getEditor().setEnabled(true);
fRHeaderColumnsGrid.setColumnOrder("header", "count");
fRHeaderColumnsGrid.sort("header");
fRHeaderColumnsGrid.getEditor().addSaveListener((EditorSaveEvent<PresentableGenerateInputHeaders> event) -> {
event.getGrid().select(event.getBean());
selectedGapFillingCountFR.add(event.getBean());
});
}
You can change methods to be more generic by identifying all the parts you don't want to keep static, and moving those to be populated by method parameters instead. I.e. instead of
private void myMethod() {
grid.setCaption("myCaption");
}
you would write
private void myMethod(String caption) {
grid.setCaption(caption);
}
and then call it
myMethod("myCaption");
If you need to be outside of the whole class to be able to determine what the real values are, you can for example make the method public or pass on the necessary values in the class constructor.
public MyClass(String gridCaption) {
myMethod(gridCaption);
}
If there are a lot of values you need to set dynamically, you might consider using an object that contains all the necessary values instead.
public void myMethod(MyPojo pojo) {
grid.setCaption(pojo.getGridCaption());
}
In your example it looks like the generic values you want to pass are DataSource dataSource and whatever type of collection selectedGapFillingCountWINTS and selectedGapFillingCountFR happen to be, and the method should probably return the grid rather than set it directly to a class variable.
I had to create an account to ask this question because I couldn't find the right way to do this. The only thing that comes close is this question here, but it doesn't go all the way and I'm still stuck. Here we go...
I'm trying to build an app following as much of the Architecture Components principles.
I'm currently trying to add a row in one of my database table, and get the ID of this row in return, to then insert a row in another table, with a reference to the first one.
I've created my database object:
#Entity(indices = {#Index("id")})
public class Search {
#PrimaryKey(autoGenerate = true) private int id;
...
And the corresponding DAO:
#Dao
public interface SearchDao {
#Insert
long insert(Search search);
...
As you can see, my DAO returns a long with the created ID. This is the behavior which was pointed out in the question I linked before, and documented here.
Since I'm following Android Architecture Components principles, I'm using a Repository class to do all my database related work. In this Repository, I've created a public method to insert a new object, which is creating and executing an AsyncTask to do the work:
public class Repository {
public void insertSearch(Search search) {
new insertSearchAsyncTask(this.mSearchDao).execute(search);
}
...
private static class insertSearchAsyncTask extends AsyncTask<Search, Void, Long> {
private SearchDao mAsyncTaskDao;
insertSearchAsyncTask(SearchDao dao) {
this.mAsyncTaskDao = dao;
}
#Override
protected Long doInBackground(final Search... params) {
long id = this.mAsyncTaskDao.insert(params[0]);
return id;
}
}
I know I can use the onPostExecute(long id) method to do stuff with the result of the doInBackground method, but this onPostExecute method cannot return anything to the insertSearch method, where I created the AsyncTask and executed it.
I know need to change the return type of my insertSearch method to long. However if I want to have something to return, I need to get the result of the execution of the AsyncTask. How can I do that?
I've tried this (according to the validated answer):
public class Repository {
private long result_id = 0;
public long insertSearch(Search search) {
new insertSearchAsyncTask(this.mSearchDao).execute(search);
return result_id;
}
private class insertSearchAsyncTask extends AsyncTask<Search, Void, Long> {
private SearchDao mAsyncTaskDao;
insertSearchAsyncTask(SearchDao dao) {
this.mAsyncTaskDao = dao;
}
#Override
protected Long doInBackground(final Search... params) {
long id = this.mAsyncTaskDao.insert(params[0]);
return id;
}
#Override
protected void onPostExecute(Long search_id) {
result_id = search_id;
}
}
}
But this feels very very wrong. I had to make the insertSearchAsyncTask class not-static, and I have to store the result of the insert in an attribute of my Repository.
I'm hoping there is a better/correct way of doing this.
I've also looked at other suggested answers on the link above, especially one about Delegates, but this doesn't suit my need as I need the method insertSearch to return the result, not another one called by the AsyncTask when it finishes.
I hope I've explained my problem clearly enough.
Any idea anyone?
Thanks a lot!!
Say I have the following class, with a list as a field:
class Group {
private List<Tile> tiles;
public Group(List<Tile> tiles) {
this.tiles = tiles;
}
public Group() {
this(new LinkedList<>());
}
public List<Tile> getTiles() {
return tiles;
}
}
What would be the best way to ensure the list is in a valid state each time elements are added/removed? (Currently the Tile class doesn't contain any setters so I don't need to worry about elements being modified.)
One possible way is to add a boolean field valid, and a method that updates valid, called after each time an element is added/removed:
class Group {
// ...
private boolean valid;
// ...
public void updateValid() {
// Check list is valid...
valid = true; // Updates `valid`
}
}
Example usage:
group.getTiles().add(new Tile());
group.updateValid();
However, with this there is the possibility of the valid field becoming inconsistent with the list (e.g. if one forgets to call updateValid after adding/removing an element).
Edit
I've since realised a simpler way is to just have a method returning a boolean rather than updating a boolean field, but I'm not sure if this is ideal as it's still possible for the list to be in an invalid state.
The safest solution is to expose individual methods controlling access to the list, instead exposing the entire object:
class Group {
private List<Tile> tiles;
public Group(List<Tile> tiles) {
// defensive copy
this.tiles = new LinkedList<>(tiles);
}
public Group() {
this.tiles = new LinkedList<>();
}
public boolean add(Tile tile) {
// validate *before* inserting
return validate(tile) && tiles.add(tile);
}
}
If your validation logic involves other elements in the list, you can calculate it after inserting:
public void add(Tile tile) {
tiles.add(tile);
updateValid(); // or throw IllegalStateException
}
Another approach would be to use lazy validation instead of expecting the client to call an extra method:
public boolean isValid() {
boolean valid = ... // validation logic here
return valid;
}
Depending on your read/write ratio, this could be more or less expensive than the eager validation you're proposing.
The updateValid() method is a good idea to validate the adding/removing operation.
To force the constraint, this method should not be called by client of the class as in your usage example but by the internal of the class, that is : any method of Group that modifies the List should call the private updateValid() method.
Besides, which is the usefulness of the boolean valid field?
If a validation fails, should you not stop the processing and throw an exception ?
Otherwise, it means that the current state of the Group object could be inconsistent. Which seems undesirable.
You could do it for example :
private void updateValid() {
if (...){ // is not valid
throw new IllegalArgumentException("modification not valid");
}
}
At last, as shmosel said, you should also avoid to provide a public method that get the real list. You could do a defensive copy to avoid change by the clients :
public List<Tile> getTiles() {
return new LinkedList(tiles);
}
I have some code that is similar to the following:
public class exampleClass {
public void main(){
defineVariable();
nextMethod();
}
void nextMethod(){
list[8] = "threw away";
}
void defineVariable(){
String[] list = {"trivial string","more trivial strings",
"just another trivial string","tr","a","sd",
"godzilla","ate","my","pony","and homework","trivial"};
}
}
And I cant access list in nextMethod.How can I fix this problem , it may seem trivial to make such a small array global but the actual arrays are in the hundreds (hence the fact I didnt c+p my actual code although if this is necessary I wont mind in the least).
Thanks very much and as a side note this is in Android although I doubt that that will effect the java code (am I wrong to assume this?).
Anyway thanks again! Ive been using StackOverflow alot lately and have only contributed a bit so from now on I will attempt to answer as many questions as I can.
Thanks,
Simply declare it in class.
public class exampleClass {
public void main()
{
nextMethod(defineVariable());
}
void nextMethod(String[] list)
{
list[8] = "threw away";
}
private String tab[] defineVariable()
{
String[] list= {"trivial string","more trivial strings","just another trivial string","tr","a","sd",
"godzilla","ate","my","pony","and homework","trivial"};
return list
}
}
If you let defineVariable be void and create a variable within its own scope, that variable just disappears into oblivion upon finished exection. Instead, have defineVariable return the list and then use this list as a parameter to the nextMethod() function.
A neat way to store many variables is to group them into different objects.
That way variables that are related can be put into the same object and the number of variables in your main class is reduced to a managable number.
In the example below, I have made the variables public. If you prefer, you can create getters and setters instead.
public class Actions {
public String humans[] = { "sit", "stand", "eat", "walk", "run", "drive", ride" };
public String dogs[] = { "sit", "stand", "bark", "run" };
public String sharks[] = { "swim", "attack" };
}
public class Equipment {
public String armour[] = { "leather", "chainmail", "plate" };
public String weapon[] = { "sword", "axe", "dagger" };
}
I am going to develop a web crawler using java to capture hotel room prices from hotel websites.
In this case I want to capture room price with the room type and the meal type, so my algorithm should be intelligent to handle that.
For example:
Room type: Deluxe
Meal type: HalfBoad
price : $20.00
The main problem is room prices can be in different ways in different hotel sites. So my algorithm should be independent from hotel sites.
I am plan to use above room types and meal types as a fuzzy sets and compare the words in webpage with above fuzzy sets using a suitable membership function.
Anyone experienced with this? or have an idea for my problem?
There are two ways to approach this problem:
You can customize your crawler to understand the formats used by different Websites; or
You can come up with a general ("fuzzy") solution.
(1) will, by far, be the easiest. Ideally you want to create some tools that make this easier so you can create a filter for any new site in minimal time. IMHO your time will be best spent with this approach.
(2) has lots of problems. Firstly it will be unreliable. You will come across formats you don't understand or (worse) get wrong. Second, it will require a substantial amount of development to get something working. This is the sort of thing you use when you're dealing with thousands or millions of sites.
With hundreds of sites you will get better and more predictable results with (1).
As with all problems, design can let you deliver value adapt to situations you haven't considered much more quickly than the general solution.
Start by writing something that parses the data from one provider - the one with the simplest format to handle. Find a way to adapt that handler into your crawler. Be sure to encapsulate construction - you should always do this anyway...
public class RoomTypeExtractor
{
private RoomTypeExtractor() { }
public static RoomTypeExtractor GetInstance()
{
return new RoomTypeExtractor();
}
public string GetRoomType(string content)
{
// BEHAVIOR #1
}
}
The GetInstance() ,ethod lets you promote to a Strategy pattern for practically free.
Then add your second provider type. Say, for instance, that you have a slightly more complex data format which is a little more prevalent than the first format. Start by refactoring what was your concrete room type extractor class into an abstraction with a single variation behind it and have the GetInstance() method return an instance of the concrete type:
public abstract class RoomTypeExtractor
{
public static RoomTypeExtractor GetInstance()
{
return SimpleRoomTypeExtractor.GetInstance();
}
public abstract string GetRoomType(string content);
}
public final class SimpleRoomTypeExtractor extends RoomTypeExtractor
{
private SimpleRoomTypeExtractor() { }
public static SimpleRoomTypeExtractor GetInstance()
{
return new SimpleRoomTypeExtractor();
}
public string GetRoomType(string content)
{
// BEHAVIOR #1
}
}
Create another variation that implements the Null Object pattern...
public class NullRoomTypeExtractor extends RoomTypeExtractor
{
private NullRoomTypeExtractor() { }
public static NullRoomTypeExtractor GetInstance()
{
return new NullRoomTypeExtractor();
}
public string GetRoomType(string content)
{
// whatever "no content" behavior you want... I chose returning null
return null;
}
}
Add a base class that will make it easier to work with the Chain of Responsibility pattern that is in this problem:
public abstract class ChainLinkRoomTypeExtractor extends RoomTypeExtractor
{
private final RoomTypeExtractor next_;
protected ChainLinkRoomTypeExtractor(RoomTypeExtractor next)
{
next_ = next;
}
public final string GetRoomType(string content)
{
if (CanHandleContent(content))
{
return GetRoomTypeFromUnderstoodFormat(content);
}
else
{
return next_.GetRoomType(content);
}
}
protected abstract bool CanHandleContent(string content);
protected abstract string GetRoomTypeFromUnderstoodFormat(string content);
}
Now, refactor the original implementation to have a base class that joins it into a Chain of Responsibility...
public final class SimpleRoomTypeExtractor extends ChainLinkRoomTypeExtractor
{
private SimpleRoomTypeExtractor(RoomTypeExtractor next)
{
super(next);
}
public static SimpleRoomTypeExtractor GetInstance(RoomTypeExtractor next)
{
return new SimpleRoomTypeExtractor(next);
}
protected string CanHandleContent(string content)
{
// return whether or not content contains the right format
}
protected string GetRoomTypeFromUnderstoodFormat(string content)
{
// BEHAVIOR #1
}
}
Be sure to update RoomTypeExtractor.GetInstance():
public static RoomTypeExtractor GetInstance()
{
RoomTypeExtractor extractor = NullRoomTypeExtractor.GetInstance();
extractor = SimpleRoomTypeExtractor.GetInstance(extractor);
return extractor;
}
Once that's done, create a new link for the Chain of Responsibility...
public final class MoreComplexRoomTypeExtractor extends ChainLinkRoomTypeExtractor
{
private MoreComplexRoomTypeExtractor(RoomTypeExtractor next)
{
super(next);
}
public static MoreComplexRoomTypeExtractor GetInstance(RoomTypeExtractor next)
{
return new MoreComplexRoomTypeExtractor(next);
}
protected string CanHandleContent(string content)
{
// Check for presence of format #2
}
protected string GetRoomTypeFromUnderstoodFormat(string content)
{
// BEHAVIOR #2
}
}
Finally, add the new link to the chain, if this is a more common format, you might want to give it higher priority by putting it higher in the chain (the real forces that govern the order of the chain will become apparent when you do this):
public static RoomTypeExtractor GetInstance()
{
RoomTypeExtractor extractor = NullRoomTypeExtractor.GetInstance();
extractor = SimpleRoomTypeExtractor.GetInstance(extractor);
extractor = MoreComplexRoomTypeExtractor.GetInstance(extractor);
return extractor;
}
As time passes, you may want to add ways to dynamically add new links to the Chain of Responsibility, as pointed out by Cletus, but the fundamental principle here is Emergent Design. Start with high quality. Keep quality high. Drive with tests. Do those three things and you will be able to use the fuzzy logic engine between your ears to overcome almost any problem...
EDIT
Translated to Java. Hope I did that right; I'm a little rusty.