Hi I am writing a program with some crazy logic and I have several loops. I need to access the variable 'Sets' outside my first loop. How can I do that?
class Example1 {
public static String sets = new String();
static Set<String> reports(){
try{
String sets = "";
fir(i=1; i<3; i++){
While(bufferedReader.readLine() != null){
if (condition1){
if(condition2){
for(condition3){
if(condition4){
sets = ("test1" + "test2");
for(condition5){
sets = sets.concat("test3");
}
}
}
}
}
}
}
}
}
// ****** I need to access sets here *******
}
You need to define the variables you want to use at the level you want to use them. e.g. if you want to access them at the outer most level of you method you need to define them at the output most level of your method, e.g. at the start of the method.
BTW: I suggest you use the formatter in your IDE to ensure your code is readable. e.g.
class Example1 {
static Set<String> reports() {
Set<String> sets = new HashSet<>();
try {
for (int i = 1; i < 3; i++) {
String line;
while ((line = bufferedReader.readLine()) != null) {
if (condition1) {
if (condition2) {
for (condition3) {
if (condition4) {
sets.add("test1");
sets.add("test2");
for (condition5) {
sets.add("test3");
}
}
}
}
}
}
}
} finally {
}
return sets;
}
}
Note: since you are just processing data, with input from a file and output of a Set, it is highly likely you should be using Java 8 streams, however it is not clear from your example exactly what you are trying to do.
Related
I periodically check if a string which I get from a web service changed. This works just fine but if an old string is deleted from my method triggers, too.
For Example:
//I get this at the beginning
"One,Two,Three"
//And at the next check I get this
"Two,Three"
So the String changed and my method returned true like it is supposed to do.
But I only want to return true if e.g. "Four" is added to the string.
Can anyone give me a solution for this problem?
Thank you a lot,
Freezed
if (!oldstring.contains(newstring)))
return true;
Perhaps you could use split like so
public class MyClass {
public static void main(String args[]) {
String oldString = "This,Is,A,Test";
String[] oldItems = oldString.split(",");
String newString = "This,Is,A,New";
String[] newItems = newString.split(",");
// For each new item, check all old items
for (String newItem: newItems)
{
Boolean foundItem = false;
for (String oldItem: oldItems)
{
// Item was already in the old items
if (newItem.equals(oldItem))
{
foundItem = true;
break;
}
}
// New item is not in the old list of items
if (!foundItem)
{
System.out.println("New item added: " + newItem);
}
}
}
}
Something like
newString.contains(oldString) && !newString.equals(oldString)
Why not just trigger when the length of the string increases? The question doesn't state that what is being added matters--only whether something is being added at all.
boolean result = false;
if(newString.length() > oldString.length()) {
result = true;
break;
}
return result;
EDIT: Based on further clarification, I understand that the length of the string is not the best indicator, since something can be removed and added at the same time, in which case OP wants true returned--even if length is shorter. Here's a solution that splits the strings into tokens, and then checks whether the last token of the old string occurs before the last token of the new string, because that means something was added after it:
boolean result = false;
String delim = ",";
String oldStringTokens[] = oldString.split(delim);
String newStringTokens[] = newString.split(delim);
for(int i = 0; i < newStringTokens.length; i++) {
if(oldStringTokens[oldStringTokens.length-1].equals(newStringTokens[i])) {
if(i < newStringTokens.length - 1) {
result = true;
}
}
}
return result;
I have more than 15 lists of strings, each list contains several different codes. Each list contains codes of one specific type.
I have one input code and have to find out which list that input code belongs to and return one specific String based on the result. I have used if, else if to do that. Below is sample code
private static String getCodeType(String inputCode) {
if (MyClass.getCodeTypeOneList().contains(inputCode)) {
return "CodeType_A";
} else if (MyClass.getCodeTypeTwoList().contains(inputCode)) {
return "CodeType_B";
} else if (MyClass.getCodeTypeThreeList().contains(inputCode)) {
return "CodeType_C";
} else if (MyClass.getCodeTypeFourList().contains(inputCode)) {
return "CodeType_D";
} else if (MyClass.getCodeTypeFiveList().contains(inputCode)) {
"CodeType_E;
} else if (MyClass.getCodeTypeixList().contains(inputCode)) {
return "CodeType_F";
} else if (MyClass.getWithDrawalCodeTypeList().contains(inputCode)) {
return "CodeType_G";
}
// similar 10 more if conditions
else {
return null;
}
}
Each List is like below:
public static List codeTypeOneList = new ArrayList();
public static final List<String> getCodeTypeOneList() {
codeTypeOneList.add("AFLS");
codeTypeOneList.add("EAFP");
codeTypeOneList.add("ZDTC");
codeTypeOneList.add("ZFTC");
codeTypeOneList.add("ATCO");
return codeTypeOneList;
}
(similar list for other code types)
is there any better way to achieve this? Thanks
As a one-time step, build a map:
Map<String, String> codeTypeMap = new HashMap<>();
for (String key : getCodeTypeOneList()) {
codeTypeMap.put(key, "CodeType_A");
}
for (String key : getCodeTypeTwoList()) {
codeTypeMap.put(key, "CodeType_B");
}
// ...
(You need to make sure either that no list element occurs in multiple lists; or to add them in order of reverse preference so that later code types overwrite earlier ones).
Then just use codeTypeMap.get to look up the type for the given code.
private static String getCodeType(String inputCode) {
return codeTypeMap.get(inputCode);
}
I have a code snippet similar to the one below,
public ArrayList getReport(reportJDOList,accountType)
{
String abc = "";
for(ReportJDO reportJDO : reportJDOList)
{
if(accountType.equals("something")
abc = reportJDO.getThis();
else
abc = reportJDO.getThat();
//somecode goes here
}
returning List;
}
As I know the value of accountType before the iteration, I dont want this check to happen, for every entry in a list as it would cause numerous number of checks if the size of reportJDOList is 10000 for an instance. How we remove this thing from happening? Thanks in Advance :)
You can indeed peform check once and implement 2 loops:
if(accountType.equals("something") {
for(ReportJDO reportJDO : reportJDOList) {
abc = reportJDO.getThis();
}
} else {
for(ReportJDO reportJDO : reportJDOList) {
abc = reportJDO.getThat();
}
}
Obviously you can improve your design by either
separating you loops into 2 different methods
Using command pattern, i.e. implementing loop body in different command and executing it to loop.
Using Guava's Function (it is just improvement of #2)
Using java 8 streams.
IF you want to save the String comparison, make it once before the loop and store the result in a boolean variable :
String abc = "";
boolean isThis = accountType.equals("something");
for(ReportJDO reportJDO : reportJDOList) {
abc = isThis ? reportJDO.getThis() : reportJDO.getThat();
//somecode goes here
}
I'd vote for clean coding this - perform the check once and delegate the logic into private methods, each performing the loop individually. This duplicates code for the loop but gives greatest flexibility if at some point you need to do something more in SomethingReport that's not duplicated in OtherReport.
public ArrayList getReport(reportJDOList,accountType) {
if("soemthing".equals(accountType)) {
return getSomethingReport(reportJDOList);
} else {
return getOtherReport(reportJDOList);
}
}
private ArrayList getSomethingReport(reportJDOList) {
[...]
}
interface AccountHandler {
String get(Report r);
}
AccountHandler thisHandler= new AccountHandler() {
#Override
public String get(Report r) {
return r.getThis();
}
};
AccountHandler thatHandler= new AccountHandler() {
#Override
public String get(Report r) {
return r.getThat();
}
};
//...............
AccountHandler ah;
ah = (what.equalsIgnoreCase("this")) ? thisHandler : thatHandler;
Report r=new Report();
// loop
ah.get(r);
//Using reflection:
Report r = new Report();
Method thisMethod = r.getClass().getDeclaredMethod("getThis");
Method thatMethod = r.getClass().getDeclaredMethod("getThat");
Method m = (what.equalsIgnoreCase("this")) ? thisMethod : thatMethod;
m.invoke(r);
The user enters an expression. Suppose user entered the following as input:
new y java.util.ArrayList int:5
i have successfully tokenized the string and stored it into different locations of my String array. next thing i want to do is that i should check whats on the index and do things according as mentioned in the above input for reflection. Am stuck how to do it. here is my code so far
public static void handling_input()
{
System.out.println("Welcome To Java Command Prompt: ");
aLine = null;
try
{
System.out.println("Enter The Command Line Expression: ") ;
keyboard = new BufferedReader(new InputStreamReader(System.in));
aLine = keyboard.readLine();
st = new StringTokenizer(aLine);
dt = new StringTokenizer(aLine);
}
catch (IOException ex)
{
System.out.println("Error reading input!");
}
}
public static void storing_tokens()
{
int counter =0;
while(st.hasMoreTokens())
{
counter++;
st.nextToken();
}
int i=0;
expression_keeper= new String[counter];
do
{
expression_keeper[i] = dt.nextToken().toString();
i++;
}while(dt.hasMoreTokens());
}
public static void token_classification()
{
for(int i=0; i<expression_keeper.length; i++)
{
if(expression_keeper[0].equalsIgnoreCase("new"))
{
}
else
if(expression_keeper[0].equalsIgnoreCase("call"))
{
}
else
if(expression_keeper[0].equalsIgnoreCase("print"))
{
}
else
{
System.out.println("Invalid Script!");
}
}
}
}
Inside this if condition:
if(expression_keeper[0].equalsIgnoreCase("new"))
{
}
i want to create the specified class,its object and assign values to the modifiers mentioned!
It is unclear to me what your input string tokens really mean. Is "java.util.ArrayList" the type for "y" and should it have an initial size of 5 units? Or should the first element be an integer of 5?
In the past I have found writing my own syntax tokenizer and parser a complicated thing to do. Even in simple cases I have often found that using something like JavaCC was easier in the long run.
By specifying your syntax formally you give much but structure to your code and it's debuggability. And then as said elsewhere use introspection to do the creation. The packages to do this are in java.lang.reflect.
I have a program in java that I wrote to return a table of values. Later on as the functions of this program grew I found that I would like to access a variable within the method that isn't returned but I am not sure the best way to go about it. I know that you cannot return more than one value but how would I go about accessing this variable without a major overhaul?
here is a simplified version of my code:
public class Reader {
public String[][] fluidigmReader(String cllmp) throws IOException {
//read in a file
while ((inpt = br.readLine()) != null) {
if (!inpt.equals("Calls")) {
continue;
}
break;
}
br.readLine();
inpt = br.readLine();
//set up parse parse parameters and parse
prse = inpt.split(dlmcma, -1);
while ((inpt = br.readLine()) != null) {
buffed.add(inpt);
}
int lncnt = 0;
String tbl[][] = new String[buffed.size()][rssnps.size()];
for (int s = 0; s < buffed.size(); s++) {
prse = buffed.get(s).split(dlmcma);
//turns out I want this smpls ArrayList elsewhere
smpls.add(prse[1]);
//making the table to search through
for (int m = 0; m < prse.length; m++) {
tbl[lncnt][m] = prse[m];
}
lncnt++;
}
//but I return just the tbl here
return tbl;
}
Can anyone recommend a way to use smpls in another class without returning it? Is this perhaps when you use a get/set sort of setup?
Sorry if this seems like an obvious question, I am still new to the world of modular programming
Right now you have this tbl variable. Wrap it in a class and add the list to the class.
class TableWrapper {
// default accessing for illustrative purposes -
// setters and getters are a good idea
String[][] table;
List<String> samples;
TableWrapper(String[][] table, List<String> samples) {
this.table = table;
this.samples = samples;
}
}
Then refactor your method to return the wrapper object.
public TableWrapper fluidigmReader(String cllmp) throws IOException {
// your code here
String tbl[][] = new String[buffed.size()][rssnps.size()];
TableWrapper tw = new TableWrapper(tbl,smpls);
// more of your code
return tw;
}
Then later in your code where you were going
String[][] tbl = fluidigmReader(cllmp);
You instead go
TableWrapper tw = fluidigmReader(cllmp);
String[][] tbl = tw.table;
List<String> smpls = tw.samples;
If you had used a dedicated class for the return value (such as the TableWrapper mentioned in another answer), then you could add additional fields there.
That is the good thing about classes - they can be extended. But you cannot extend String[][] in Java.
You can set a field, instead of a local variable, which you can retrieve later with a getter. You want to avoid it unless it is needed, but in this case it is.
You can use class(Inside Reader class) variable for this. But make sure that it's read/write is synchronized