I am reading a text file abc .txt which is tab delimited as shown below
gfh hgh thf
--- --- ---
fgh sji irj
rhf dhh fhf
kji idj ddt
and I am able to read it successfully (for all the columns in the table I have developed a separate pojo along with getters and setters), the advantage is that I can get the value of complete row through its getters.
Now I have to make sure that no column in the table should be null and if any column value is null, then I should throw a new exception, for example ..
gfh hgh thf
--- --- ---
fgh sji irj //row 1
rhf dhh fhf
kji idj ddt
fgq fio //As seen in this row that second column value is null
Now the approach that I am following is that getting the value row wise in a string as shown below
String n = f.getgfh()+f.gethgh()+f.getthf(); //it will contain the contents of the row 1
make a separate method and will pass this string
private boolean validaterow(String f)
{
}
in this method here I am taking the complete row in a string and inside this method I want to break this string in tokens and then further evaluate those tokens for empty or null , if there are then I will return false
Try this,
private boolean validateRow(String f)
{
if(f.getgfh() != null && !f.getgfh().trim().isEmpty() &&
f.gethgh() != null && !f.gethgh().trim().isEmpty() &&
f.getthf() != null && !f.getthf().trim().isEmpty())
{
return true;
}
else
{
return false;
}
}
You can set a null check like in getters
public String gethgh()
{
return (String) ((null == hgh) ? new UserDefinedException() : hgh);
}
here UserDefinedException must be declared as a class
I consider this should work
Why do you pass it to a method?
Use
String row1,row2,row3;
row1=f.getgfh();
row2=f.gethgh();
row3=f.getthf();
You can check for your condition at the time of concatenation.
if(row1==null)
'throw your message
else
row1=""
if(row2==null)
'throw your message
else
row2=""
if(row3==null)
'throw your message
else
row3=""
At last,
String n = row1+row2+row3;
Look at apache string utils library. It might have what you need
Split each line on tab like string.split("\t") and check each token using isEmpty() method of string class.
use StringIsNullOrEmtpy to check if row is valid for every entry of the row
private boolean ValidateRow()
{
return !(StringIsNullOrEmpty((f.getgfh())) ||
StringIsNullOrEmpty((f.gethgh())) ||
StringIsNullOrEmpty((f.getthf()))
);
}
private bool StringIsNullOrEmtpy(string input)
{
return input.isEmpty() || input == null;
}
Let's assume that you have a method getNextValueAndPosPair() which returns the next value of your tsv (tab separate values) file and the position of the last space found after the value read (i.g. a Tab or a Newline).
Then you can validate your input row by chechking that it contains exactly three distinct values separated by a Tab.
Below the implementation:
// A simple general pair class.
class Pair<A, B> {
Pair(A first, A second) {
this.first = first;
this.second = second;
}
public A first() { return first; }
public A second() { return second; }
private final A first;
private final B second;
}
// Returns true if this rows contains 4 distinct values, false otherwise.
private boolean validaterow(String f) {
int pos = 0;
for (int i = 0; i < 3; i++) {
Pair<String, Integer> valueAndPos = getNextValueAndPosPair(f, pos);
String value = valueAndPos.first();
int pos = valueAndPos.second();
if (value.isEmpty()) {
System.err.println("The " + i + "-th value is null.");
return false;
}
pos += 1;
}
return true;
}
// Returns a Pair holding the next tsv value in the row and the position of the delimiter space
private Pair<String, Integer> getNextValueAndPosPair(String f, int start) {
int length = 0;
for (int i = start; i < f.length && !Character.isSpaceChar(f.charAt(i)); i++) length++;
int end = start + length;
String value = f.substring(start, end);
Pair<String, Integer> valueAndPos = new Pair<>(value, end);
return valueAndPos;
}
Related
I am trying to write as few lines as possible.
What would be the best way to re-write this in Java? (say we have a "public enum A")
I want to have a way of writing "if something is not null, return it, otherwise, keep going".
I looked into Optional, but Optional.of(...).ifPresent( v -> return v;) does not work, although I wish it did.
Also, if you are asking why I am changing the array inside a for-loop, you can consider that there are multiple initial arrays and I need to test them each.
public A getAValue() {
int[] arr = new int[7];
A returnValue = null;
for (int i=0; i<10; i++) {
//change arr
returnValue = checkSomeCondition(arr);
if (returnValue != null) {
return returnValue;
}
//change arr again
returnValue = checkSomeCondition(arr);
if (returnValue != null) {
return returnValue;
}
//change arr yet again
returnValue = checkSomeCondition(arr);
if (returnValue != null) {
return returnValue;
}
}
return A.UNKNOWN;
}
public A checkSomeCondition(int[] arr) {
if (arr[0]==arr[1]) {
return arr[0]==2 ? A.VALUE_1 : A.VALUE_2;
}
return null;
}
Q: I looked into Optional, but Optional.of(...).ifPresent( v -> return v;) does not work, although I wish it did
Optional::ifPresent works, but different than intended. The return is within the method implementation of the Consumer. Moreover, the Consumer doesn't return anything, the method return type is void.
Q: I am trying to write as few lines as possible.
You achieve what you want with the help of a predefined set of the array suppliers Supplier<int[]> and another for-loop inside the already existing one with a number of iterations the same as a number of conditions.
List<Supplier<int[]>> arrays = new ArrayList<>();
arrays.add(() -> firstArraySource());
arrays.add(() -> secondArraySource());
...
for (...) { // your initial loop
for (Supplier<int[]> arraySupplier: arrays) { // iterate through Suppliers
arr = arraySupplier.get(); // get an array (here is the evaluation)
returnValue = checkSomeCondition(arr); // getting the 'A' value
if (returnValue != null) { // returnin if not null
return returnValue;
}
}
}
The advantage of this approach is that if the sources of arrays are ex. from the database, they won't be called before they are actually needed since they are wrapped in the Suppliers. The calculaiton happens when Supplier::get is called.
Not clear what kind of test your doing or how you are alteringyour arrays but this may be possible:
This should ignore all null return values and only return the first successful test result.
If no successes, a default return object must be supplied.
enum A {
A_VALUE_1, A_VALUE_2, A_UNKNOWN
};
List<Object[]> testArrays = new ArrayList<>();
testArrays.add(new int[] { 1, 2, 3 });
testArrays.add(new int[] { 3, 4, 5 });
testArrays.add(new int[] { 2, 2, 6 });
A res =
// stream the set of arrays
testArrays.stream()
// apply each set in order to the method
// replacing the array under test with the
// method result
.map(arr->checkSomeCondition(arr))
// filter out any null results
.filter(result->result!=null)
// get the first non-null result
.findFirst()
// return the result or some default answer if all
// results were null.
.orElseGet(()->A.A_UNKNOWN);
System.out.println(res);
With the supplied data, prints
A_VALUE_1
Your test method
public A checkSomeCondition(int[] arr) {
if (arr[0] == arr[1]) {
return arr[0] == 2 ? A.A_VALUE_1 : A.A_VALUE_2;
}
return null;
}
The down side is it requires you to supply an array of arrays where subsequent ones are to be used if the previous test fails. You may be able to adapt the concept to your requirements.
Use Optional.ofNullable instead of Optional.of as the latter can't be used for possibly null values. That would work, as well as delegating that task to checkSomeCondition function:
public Optional<A> checkSomeCondition(int[] arr) {
if (arr[0] == arr[1]) {
return Optional.<A>of(arr[0]==2 ? A.VALUE_1 : A.VALUE_2);
}
return Optional.<A>empty();
}
...and then checking the presence of value in getAValue.
The condition can then be checked in a loop, i.e.
public A getAValue() {
int[] arr = new int[7];
final int maxChecks = 10;
Optional<A> returnValue = Optional.<A>empty();
for (int i = 0; i < 10; i++) {
int j = 0;
while (!returnValue.isPresent() && j < maxChecks) {
returnValue = checkSomeCondition(arr);
j++;
}
return returnValue.get();
}
return A.UNKNOWN;
}
I have a whole bunch of rows that contain tax payments.
Each row contains PaymentDueDate.
If row is missing in between PaymentDueDates, I have to use same values from previous row to aggregate for all totals.
In below example, between Row="2" and Row="3", data is missing for months 2015/09, 2015/10, 2015/11, 2015/12, 2016/01, 2016/02.
So, I have to use Row="2" values to use to account for missing rows.
<PaymentChangeMaintenance>
<PaymentChangeMaintenanceTransaction Row="1">
<BuydownSubsidyAmount>0.00</BuydownSubsidyAmount>
<AnnualInterestRate>4.75000</AnnualInterestRate>
<PIAmount>689.79</PIAmount>
<PaymentDueDate>2015-07-01</PaymentDueDate>
<CityTaxAmount>23.22</CityTaxAmount>
<CountyTaxAmount>32.25</CountyTaxAmount>
</PaymentChangeMaintenanceTransaction>
<PaymentChangeMaintenanceTransaction Row="2">
<BuydownSubsidyAmount>0.00</BuydownSubsidyAmount>
<AnnualInterestRate>4.75000</AnnualInterestRate>
<PIAmount>689.79</PIAmount>
<PaymentDueDate>2015-08-01</PaymentDueDate>
<CityTaxAmount>125.25</CityTaxAmount>
<CountyTaxAmount>666.22</CountyTaxAmount>
</PaymentChangeMaintenanceTransaction>
<PaymentChangeMaintenanceTransaction Row="3">
<BuydownSubsidyAmount>0.00</BuydownSubsidyAmount>
<AnnualInterestRate>4.75000</AnnualInterestRate>
<PIAmount>689.79</PIAmount>
<PaymentDueDate>2016-03-01</PaymentDueDate>
<CityTaxAmount>125.25</CityTaxAmount>
<CountyTaxAmount>666.22</CountyTaxAmount>
</PaymentChangeMaintenanceTransaction>
</PaymentChangeMaintenance>
Here is code someone wrote, but it is not clean-looking. I would like to use for-each :/
private void aggregateEscrowPaymountAmounts(List<PaymentChangeMaintenanceFieldsV214Type> fieldsType,
PaymentChangeMaintenance paymentChangeMaintenance, final int numberOfTrialPayments) {
AtomicInteger cnt = new AtomicInteger(1);
Iterator<PaymentChangeMaintenanceFieldsV214Type> fieldsTypeIterator = fieldsType.iterator();
PaymentChangeMaintenanceFieldsV214Type fieldType = fieldsTypeIterator.next();
PaymentChangeMaintenanceFieldsV214Type nextFieldType = null;
if (fieldsTypeIterator.hasNext()) {
nextFieldType = fieldsTypeIterator.next();
}
LocalDate monthDate = fieldType.getNextPaymentDueDate();
while (cnt.getAndIncrement() <= numberOfTrialPayments) {
PaymentChangeMaintenance tempPaymentChangeMaintenance = createPaymentChangeMaintenanceEscrow(fieldType);
paymentChangeMaintenance.aggregate(tempPaymentChangeMaintenance);
monthDate = monthDate.plusMonths(1);
if (nextFieldType != null) {
LocalDate nextFieldTypeDate = nextFieldType.getNextPaymentDueDate();
if (nextFieldTypeDate.getMonthValue() == monthDate.getMonthValue()) {
fieldType = nextFieldType;
if (fieldsTypeIterator.hasNext()) {
nextFieldType = fieldsTypeIterator.next();
} else {
nextFieldType = null;
}
}
}
}
}
For this certain case you can use a following approach: determine a step - for you it's a month. Then initialize a default value for a case of absence of the value on the next step. Then use some method that will take a next value and default value and depends on a step presence will return one of them
Here is a pseudocode:
List<Item> items;
Item nextItem = items.get(0);
Value step = month;
for (int i = 1; i < items.size(); i++) {
nextItem = getNextItem(items.get(i), nextItem, step);
****
}
Item getNextItem(Item nextItem, Item defaultItem, Value step) {
if (!nextItem.getStepValue().equals(calcNext(step))) {
return defaultItem;
} else {
return nextItem;
}
}
StepValue calcNext(Value step) {
/*some calculations. In your case month increment*/
}
HashMap intermediateIdMap = new HashMap(d_idMap.size());
int linkCounter = 0;
for (Iterator it = d_idMap.entrySet().iterator(); it.hasNext(); )
{
Map.Entry me = ((Map.Entry) it.next());
long oldId = (Long) me.getKey();
MapObject mo = d_mc.findMapObject(oldId);
if (mo != null && !isMetaDataType(mo)
&& (IdSpace.isTransient(mo.id()) || d_updateAllIds
|| isNegativeIdUpdate(mo.id())))
{
int transientId = d_idGenerator.getNewId();
I need to get the first transientId when its executed for the very first time and the Id it sets and also the last Id i.e MIN_TRANSIENT and MAX_TRANSIENT
I tried changing the Data Structure to LinkedHashMap which would have given me the 1st and Last element easily but i guess seniors dont want me to change the ds, do you guys help me find an another way
public synchronized int getNewId()
{
// Contract.precondition("Within range", d_currentId <= d_range);
// CMSDL-3988 - recycle/reset the currentId once max reached
if(d_currentId>d_range)
d_currentId=MIN_TRANSIENT;
return d_currentId++;
}
If you need changes for a reason, you should be allowed to do them.
Otherwise, you need some structure around your code such as
boolean firstValueSeen = false;
int firstValue = -1;
for (…) {
…
int transientId = d_idGenerator.getNewId();
firstValueSeen = true;
firstValue = transientId
I been at it for a while I can't figure it out. I am suppose to do a reverse order traversal (right-root-left) and pass the level of the root to the function ShowTree.
What exactly is the level of the root? Is it the height? If yes, this is the code for it:
public int getHeight()
{
return getHeight(_root);
}
private int getHeight (BSTnode top)
{
if (top == null)
return 0;
else
{
int lftHeight = getHeight(top._left);
int rhtHeight = getHeight(top._right);
if (lftHeight > rhtHeight)
return 1 + lftHeight;
else
return 1 + rhtHeight;
}
}
So I assign the value of getHeight to level and pass it to ShowTree. I am suppose to use the level of each node to compute how many spaces to insert in front of the data of each node.
public String ShowTree (int level)
{
return ShowTree(_root,level);
}
private String ShowTree(BSTnode myroot, int level)
{
String result = "";
if (myroot == null)
return "";
else
{
result += ShowTree (myroot._right, level + 1);
result += myroot._data.toStringKey();
result += ShowTree (myroot._left, level + 1);
return result;
}
}
However this diplays the tree like this:
c
b
a
When it should print like this:
c
b
a
In your ShowTree(BSTnode, int) method...
String result = ""; // no extra whitespace
Dont you mean...
String result = " "; //extra whitespace
I am reading a text file abc .txt which is tab delimited as shown below
gfh hgh thf
--- --- ---
fgh sji irj
rhf dhh fhf
kji idj ddt
and I am able to read it successfully (for all the columns in the table I have developed a separate pojo along with getters and setters), the advantage is that I can get the value of complete row through its getters.
Now I have to make sure that no column in the table should be null and if any column value is null, then I should throw a new exception, for example ..
gfh hgh thf
--- --- ---
fgh sji irj //row 1
rhf dhh fhf
kji idj ddt
fgq fio //As seen in this row that second column value is null
Now the approach that I am following is that getting the value row wise in a string as shown below
String n = f.getgfh()+f.gethgh()+f.getthf(); //it will contain the contents of the row 1
make a separate method and will pass this string
private boolean validaterow(String f)
{
}
in this method here I am taking the complete row in a string and inside this method I want to break this string in tokens and then further evaluate those tokens for empty or null , if there are then I will return false
Try this,
private boolean validateRow(String f)
{
if(f.getgfh() != null && !f.getgfh().trim().isEmpty() &&
f.gethgh() != null && !f.gethgh().trim().isEmpty() &&
f.getthf() != null && !f.getthf().trim().isEmpty())
{
return true;
}
else
{
return false;
}
}
You can set a null check like in getters
public String gethgh()
{
return (String) ((null == hgh) ? new UserDefinedException() : hgh);
}
here UserDefinedException must be declared as a class
I consider this should work
Why do you pass it to a method?
Use
String row1,row2,row3;
row1=f.getgfh();
row2=f.gethgh();
row3=f.getthf();
You can check for your condition at the time of concatenation.
if(row1==null)
'throw your message
else
row1=""
if(row2==null)
'throw your message
else
row2=""
if(row3==null)
'throw your message
else
row3=""
At last,
String n = row1+row2+row3;
Look at apache string utils library. It might have what you need
Split each line on tab like string.split("\t") and check each token using isEmpty() method of string class.
use StringIsNullOrEmtpy to check if row is valid for every entry of the row
private boolean ValidateRow()
{
return !(StringIsNullOrEmpty((f.getgfh())) ||
StringIsNullOrEmpty((f.gethgh())) ||
StringIsNullOrEmpty((f.getthf()))
);
}
private bool StringIsNullOrEmtpy(string input)
{
return input.isEmpty() || input == null;
}
Let's assume that you have a method getNextValueAndPosPair() which returns the next value of your tsv (tab separate values) file and the position of the last space found after the value read (i.g. a Tab or a Newline).
Then you can validate your input row by chechking that it contains exactly three distinct values separated by a Tab.
Below the implementation:
// A simple general pair class.
class Pair<A, B> {
Pair(A first, A second) {
this.first = first;
this.second = second;
}
public A first() { return first; }
public A second() { return second; }
private final A first;
private final B second;
}
// Returns true if this rows contains 4 distinct values, false otherwise.
private boolean validaterow(String f) {
int pos = 0;
for (int i = 0; i < 3; i++) {
Pair<String, Integer> valueAndPos = getNextValueAndPosPair(f, pos);
String value = valueAndPos.first();
int pos = valueAndPos.second();
if (value.isEmpty()) {
System.err.println("The " + i + "-th value is null.");
return false;
}
pos += 1;
}
return true;
}
// Returns a Pair holding the next tsv value in the row and the position of the delimiter space
private Pair<String, Integer> getNextValueAndPosPair(String f, int start) {
int length = 0;
for (int i = start; i < f.length && !Character.isSpaceChar(f.charAt(i)); i++) length++;
int end = start + length;
String value = f.substring(start, end);
Pair<String, Integer> valueAndPos = new Pair<>(value, end);
return valueAndPos;
}