how to improve code quality (mostly duplicates) - java

I have a set of variables that was passed in by a mega method in an ancient legacy code.....
public List<type> check (String required, String sales, String report,
Long passId, Long seatId, String capName, String vCapName,
String attName, Long vid) {
if(required != null) {
goodA = method(required);
goodB = methodTwo(required);
goodC = methodThree(required);
}
if(sales != null) {
goodA = method(sales);
goodB = methodTwo(sales);
goodC = methodThree(sales);
}
if(report != null) {
goodA = method(report);
goodB = methodTwo(report);
goodC = methodThree(report);
if(passId != null)
... you got the point....
}
The variables that passed into check can only be 1 valid value all other variables will become null.
For example
check("Yes",null,null,null,null,null...)
or
check(null,null,null,13212L,null,null,null,null)
right now I am trying to rewrite this into something less repetitive and clean I was wondering if anyone can provide some ideas on how to do this.

How about something like this?
List<Object> items = Lists.newArrayList(required, sales, report,
capName, vCapName, attName);
for(Object item : items) {
if(item != null){
methodOne(item);
methodTwo(item);
methodThree(item);
}
}

Related

How to set multiple conditional opearator in java8

I am trying to convert the below code in java 8, but not sure where I am going wrong. I have 2 code snippets which I want to convert. This is the first one:
for (WebElement value :values) {
WebElement dateElement = SharedWebDriver.getInstance()
.findOptionalElement(By.className("text"), value);
WebElement groupElement =
SharedWebDriver.getInstance().findOptionalElement(By.id("label"),
value);
WebElement typeElement =
SharedWebDriver.getInstance().findOptionalElement(By.id("type"),
value);
if (dateElement != null) {
dateValue = dateElement.getText().trim();
}
if (groupElement != null) {
groupValue = groupElement.getText().trim();
}
if(typeElement!= null){
typeValue = typeElement.getText().trim();
}
}
And here I want to set value using java 8. I tried it with using the filter option, but it's not working.
for (WebElement header : headers) {
if (header != null) {
if (header.getText().equals("A")) {
entry.setDate(dateValue);
} else if (header.getText().equals("B")) {
entry.setGroup(groupValue);
} else if (header.getText().equals("C")) {
entry.setType(typeValue);
}
}
}
Can anyone help me?
The problem with those code snippets is that they modifiy variables defined outside of the loop (dateValue, groupValue and typeValue for the first one, and entry for the second one).
But lambda expressions are not really supposed to alter variables that are not defined in their scope event though you can achieve that throught methods.
For example, inside a lambda expression :
word = "hello" will not work whereas website.setTitle("title") will
I converted your code snippets in Java 8, I didn't take the time to test it but if I am if i am not mistaken, the first one will not work whereas the second one will, for the reason explained above.
values.stream()
.map(value -> new WebElement[] {
SharedWebDriver.getInstance().findOptionalElement(By.className("text"), value),
SharedWebDriver.getInstance().findOptionalElement(By.id("label"), value)),
SharedWebDriver.getInstance().findOptionalElement(By.id("type"), value) })
.forEach(webElements[] -> {
if (webElements[0] != null) {
dateValue = webElements[0].getText().trim();
}
if (webElements[1] != null) {
groupValue = webElements[1].getText().trim();
}
if(webElements[2] != null){
typeValue = webElements[2].getText().trim();
}
});
headers.stream()
.filter(Objects::nonNull)
.forEach(header -> {
if (header.getText().equals("A")) {
entry.setDate(dateValue);
} else if (header.getText().equals("B")) {
entry.setGroup(groupValue);
} else if (header.getText().equals("C")) {
entry.setType(typeValue);
}
});

Hibernate search - handling null in boolean query

Is there a best practice for handling optional sub-queries? So say my search service has
query = builder.bool().must(createQuery(field1, term1)).must(createQuery(field2, term2)).createQuery();
createQuery(field, term) {
if(term != null) {
return builder.keyword().onField(field).matching(term).createQuery();
}
return null;
}
With the default QueryBuilder if I use a query like this and the term is null, the resulting query is "+term1 +null" or something along those lines, which causes a null pointer exception when the query is executed against the index. Is there a recommended way to avoid this issue? I was thinking about a custom QueryBuilder but I'm not sure how to tell the fulltext session to use my implementation rather than it's default. The only other way I can think of is something like
query;
query1 = createQuery(field1, term1);
query2 = createQuery(field2, term2);
if(query1 != null && query2 != null) {
query = builder.bool().must(query1).must(query2).createQuery();
} else if(query1 != null && query2 == null) {
query = query1;
} else if(query1 == null && query2 != null) {
query = query2;
}
createQuery(field, term) {
if(term != null) {
return builder.keyword().onField(field).matching(term).createQuery();
}
return null;
}
But this gets really messy really fast if there are more than a handful of sub-queries.
What you might do is introducing a method whose sole purpose would be to add a "must" in a null-safe way. I.e. do something like this:
BooleanJunction junction = builder.bool();
must(junction, createQuery(field1, term1));
must(junction, createQuery(field2, term2));
query = junction.createQuery();
void must(BooleanJunction junction, Query query) {
if (query != null) {
junction.must(query);
}
}
Query createQuery(String field, Object term) {
if(term != null) {
return builder.keyword().onField(field).matching(term).createQuery();
}
return null;
}
This would take out the "fluidity" of the BooleanJunction API, but since it's at the top-level only, I guess it's not so bad.
what about this
org.json.JSONObject json = new org.json.JSONObject();
json.put(field1, term1);
json.put(field2, term2);
...
bool = builder.bool();
for (Iterator keys = json.keys(); keys.hasNext();) {
String field = (String) keys.next();
String term = (String) json.get(field);
q = createQuery(field, term);
if (q != null) {
bool.must(q);
}
}
query = bool.createQuery();
if you have duplicate fields with different terms you must use this :
org.json.JSONObject json = new org.json.JSONObject();
json.append(field1, term1);
json.append(field2, term2);
...
bool = builder.bool();
for (Iterator keys = json.keys(); keys.hasNext();) {
String field = (String) keys.next();
JSONArray terms = (JSONArray) json.get(field);
for (int i = 0; i < terms.length(); i++) {
String term = (String) terms.get(i);
q = createQuery(field, term);
if (q != null) {
bool.must(q);
}
}
}
query = bool.createQuery();

Segregating filtered tweets based on matched keywords : Twitter4j API

I have created twitter stream filtered by some keywords as follows.
TwitterStream twitterStream = getTwitterStreamInstance();
FilterQuery filtre = new FilterQuery();
String[] keywordsArray = { "iphone", "samsung" , "apple", "amazon"};
filtre.track(keywordsArray);
twitterStream.filter(filtre);
twitterStream.addListener(listener);
What is the best way to segregate tweets based on keywords matched. e.g. All the tweets that matches "iphone" should be stored into "IPHONE" table and all the tweets that matches "samsung" will be stored into "SAMSUNG" table and so on. NOTE: The no of filter keywords is about 500.
It seems that the only way to find out to which keyword a tweet belongs to is iterating over multiple properties of the Status object. The following code requires a database service with a method insertTweet(String tweetText, Date createdAt, String keyword) and every tweet is stored in the database multiple times, if multiple keywords are found. If at least one keyword is found in the tweet text, the additional properties are not searched for more keywords.
// creates a map of the keywords with a compiled pattern, which matches the keyword
private Map<String, Pattern> keywordsMap = new HashMap<>();
private TwitterStream twitterStream;
private DatabaseService databaseService; // implement and add this service
public void start(List<String> keywords) {
stop(); // stop the streaming first, if it is already running
if(keywords.size() > 0) {
for(String keyword : keywords) {
keywordsMap.put(keyword, Pattern.compile(keyword, Pattern.CASE_INSENSITIVE));
}
twitterStream = new TwitterStreamFactory().getInstance();
StatusListener listener = new StatusListener() {
#Override
public void onStatus(Status status) {
insertTweetWithKeywordIntoDatabase(status);
}
/* add the unimplemented methods from the interface */
};
twitterStream.addListener(listener);
FilterQuery filterQuery = new FilterQuery();
filterQuery.track(keywordsMap.keySet().toArray(new String[keywordsMap.keySet().size()]));
filterQuery.language(new String[]{"en"});
twitterStream.filter(filterQuery);
}
else {
System.err.println("Could not start querying because there are no keywords.");
}
}
public void stop() {
keywordsMap.clear();
if(twitterStream != null) {
twitterStream.shutdown();
}
}
private void insertTweetWithKeywordIntoDatabase(Status status) {
// search for keywords in tweet text
List<String> keywords = getKeywordsFromTweet(status.getText());
if (keywords.isEmpty()) {
StringBuffer additionalDataFromTweets = new StringBuffer();
// get extended urls
if (status.getURLEntities() != null) {
for (URLEntity url : status.getURLEntities()) {
if (url != null && url.getExpandedURL() != null) {
additionalDataFromTweets.append(url.getExpandedURL());
}
}
}
// get retweeted status -> text
if (status.getRetweetedStatus() != null && status.getRetweetedStatus().getText() != null) {
additionalDataFromTweets.append(status.getRetweetedStatus().getText());
}
// get retweeted status -> quoted status -> text
if (status.getRetweetedStatus() != null && status.getRetweetedStatus().getQuotedStatus() != null
&& status.getRetweetedStatus().getQuotedStatus().getText() != null) {
additionalDataFromTweets.append(status.getRetweetedStatus().getQuotedStatus().getText());
}
// get retweeted status -> quoted status -> extended urls
if (status.getRetweetedStatus() != null && status.getRetweetedStatus().getQuotedStatus() != null
&& status.getRetweetedStatus().getQuotedStatus().getURLEntities() != null) {
for (URLEntity url : status.getRetweetedStatus().getQuotedStatus().getURLEntities()) {
if (url != null && url.getExpandedURL() != null) {
additionalDataFromTweets.append(url.getExpandedURL());
}
}
}
// get quoted status -> text
if (status.getQuotedStatus() != null && status.getQuotedStatus().getText() != null) {
additionalDataFromTweets.append(status.getQuotedStatus().getText());
}
// get quoted status -> extended urls
if (status.getQuotedStatus() != null && status.getQuotedStatus().getURLEntities() != null) {
for (URLEntity url : status.getQuotedStatus().getURLEntities()) {
if (url != null && url.getExpandedURL() != null) {
additionalDataFromTweets.append(url.getExpandedURL());
}
}
}
String additionalData = additionalDataFromTweets.toString();
keywords = getKeywordsFromTweet(additionalData);
}
if (keywords.isEmpty()) {
System.err.println("ERROR: No Keyword found for: " + status.toString());
} else {
// insert into database
for(String keyword : keywords) {
databaseService.insertTweet(status.getText(), status.getCreatedAt(), keyword);
}
}
}
// returns a list of keywords which are found in a tweet
private List<String> getKeywordsFromTweet(String tweet) {
List<String> result = new ArrayList<>();
for (String keyword : keywordsMap.keySet()) {
Pattern p = keywordsMap.get(keyword);
if (p.matcher(tweet).find()) {
result.add(keyword);
}
}
return result;
}
Here's how you'd use a StatusListener to interrogate the received Status objects:
final Set<String> keywords = new HashSet<String>();
keywords.add("apple");
keywords.add("samsung");
// ...
final StatusListener listener = new StatusAdapter() {
#Override
public void onStatus(Status status) {
final String statusText = status.getText();
for (String keyword : keywords) {
if (statusText.contains(keyword)) {
dao.insert(keyword, statusText);
}
}
}
};
final TwitterStream twitterStream = getTwitterStreamInstance();
final FilterQuery fq = new FilterQuery();
fq.track(keywords.toArray(new String[0]));
twitterStream.addListener(listener);
twitterStream.filter(fq);
I see the DAO being defined along the lines of:
public interface StatusDao {
void insert(String tableSuffix, Status status);
}
You would then have a DB table corresponding with each keyword. The implementation would use the tableSuffix to store the Status in the correct table, the sql would roughly look like:
INSERT INTO status_$tableSuffix$ VALUES (...)
Notes:
This implementation would insert a Status into multiple tables if a Tweet contained 'apple' and 'samsung' for instance.
Additionally, this is quite a naive implementation, you might want to consider batching inserts into the tables... but it depends on the volume of Tweets you'll be receiving.
As noted in the comments, the API considers other attributes when matching e.g. URLs and an embedded Tweet (if present) so searching the status text for a keyword match may not be sufficient.
Well, you could create a class similar to an ArrayList but make it so you can create an array of ArrayLists, call it TweetList. This class will need an insert function.
Then use two for loops to search through the tweets and find matching keywords that are contained in a normal array list, and then add them to the TweetList that matches the index of the keyword in the keywords ArrayList
for (int i = 0; i < tweets.length; i++)
{
String[] split = tweets[i].split(" ");// split the tweet up
for (int j = 0; j < split.length; j++)
if (keywords.contains(split[j]))//check each word against the keyword list
list[keywords.indexOf(j)].insert[tweets[i]];//add the tweet to the tree index that matches index of the keyword
}

Compare field from previous row in JDBC ResultSet

I've researched can't find any relevant info. I have a result set that give me back distinct tagId's their can be multiple tagIds for same accountId's.
while(result_set.next()){
String tagId = result_set.getString("tagId");
String accountId = result_set.getString("accoundId");
// plenty of other fields being store locally
}
I need to store first accoundId(which is being done) & every subsequent iteration compare it with the previous Id to check for equality or not(if so same account).
I tried this and it failed horribly, after first iteration they'll continually be equal & I must be DUMB bc i though as long as I compare them before assignment global guy(previousId) should be holding the prior value.
String previousId = null;
while(result_set.next()){
String tagId = result_set.getString("tagId");
String accountId = result_set.getString("accoundId");
previousId = accountId;
}
Anyway I wanted my workflow to go something as follows:
while(result_set.next()){
if (previousId = null) {
// this would be the first iteration
}
else if (previousId.equals(accountId) {
// go here
} else {
// go here
}
}
If I've understood you well, this should work..
String previousId = null;
while(result_set.next()){
String tagId = result_set.getString("tagId");
String accountId = result_set.getString("accoundId");
if (previousId == null) {
// this would be the first iteration
} else if (previousId.equals(accountId) {
// go here
} else {
// go here
}
previousId = accountId;
}

Why doesn't the Sort method of my Linked List work? [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am trying to implement a sort method for a Singly Linked List. The method is suppose to go through the list, compare a pair of nodes, and place one of these at the front if needed. It uses two other methods: - Remove() (removes a specific node from list)
- InsertFront() (Insert a new node at the front of the list.
Both of these methods work by themselves and everything compiles.
public Link remove(String lastName)
{
Link current_ = first_;
Link prior_ = null;
Link found_ = null;
while (current_ != null && current_.lastName.compareTo(lastName) != 0)
{
prior_ = current_;
current_ = current_.next;
}
if(current_ != null)
{
if(prior_ == null)
{
found_ = first_;
System.out.println(current_.next.lastName);
first_ = current_.next;
}
else if(current_ == last_)
{
found_ = last_;
Link hold_ = first_;
first_ = prior_;
first_.next = current_.next;
first_ = hold_;
}
else
{
found_ = current_;
Link hold_ = first_;
first_ = prior_;
first_.next = current_.next;
first_ = hold_;
}
}
return found_;
}
public void insertFront(String f, String m, String l)
{
Link name = new Link(f, m, l);
if (isEmpty())
{
System.out.println("Adding first name");
first_ = name;
last_ = name;
}
else
{
System.out.println("Adding another name");
Link hold_ = first_;
first_ = last_;
first_.next = name;
last_ = first_.next;
first_ = hold_;
}
}
I have tried to fix it but I always run into two different problems:
It works but does not insert the link back in.
public void Sort()
{
Link temp_;
boolean swapped_ = true;
while (swapped_ == true)
{
swapped_ = false;
Link current_ = first_;
String comp_ = current_.lastName;
while (current_ != null && current_.lastName.compareTo(comp_) >= 0)
{
current_ = current_.next;
}
if (current_ != null)
{
temp_ = remove(current_.lastName);
insertFront(temp_.firstName, temp_.middleName, temp_.lastName);
swapped_ = true;
}
}
}
I receive a Null Pointer Exception.
Exception in thread "main" java. lang. NullPointerException
at List $ Link . access $000(List . java : 25)
at List . Sort ( List . java:165)
at main( java :79)
Java Result: 1
DeBugging results in:
Listening on javadebug
Not able to submit breakpoint LineBreakpoint LinearGenericSearch.java : 28, reason: The breakpoint is set outside of any class.
Invalid LineBreakpoint LinearGenericSearch.java : 28
User program running
Debugger stopped on uncompilable source code.
User program finished
public void Sort()
Link temp_;
boolean swapped_ = true;
while (swapped_ == true)
{
Link current_ = first_;
swapped_ = false;
while (current_.next != null)
{
if((current_.lastName.compareTo(current_.next.lastName)) > 0)
{
temp_ = remove(current_.next.lastName);
insertFront(temp_.firstName, temp_.middleName, temp_.lastName);
swapped_ = true;
}
current_ = current_.next;
}
}
}
My question is: What am I doing wrong? Any advice on how to avoid this next time?
In java you don't have to do all this manually!! Just use LinkedList, code for the
compareTo()
by implementing
Comparable Interface
(http://docs.oracle.com/javase/6/docs/api/java/lang/Comparable.html) and call
Collections.sort(List list, Comparator c)
(http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html)
to sort the way how ever you want to.

Categories

Resources