Check if the number in string object is between range java 8 - java

I want to check if a number in string is in a given range or not. if yes then add 100 to the number present in the string and return string.
For example channel has id name and start and end time
// created list of channel object
List<Channel> cList= Arrays.asList(
new Channel(1,"BBC","0300","0500"),
new Channel(2,"TR","0400","0509"),
new Channel(3,"NEWS","0700","0800"));
/*logic to identifyif the value is in between given rabge and add 100 to it.*/
List<Channel> cNewList=cList.forEach(
// perform operation to find if c.getstartTime() between
// range(100,500).then add 100 in it.
);
I know we can use Integer.parseInt(String) method to convert to integer value but I want the output back to a string.

Assuming that you class Channel has these member fields:
class Channel {
private int index;
private String name;
private String startTime;
private String endTime;
...
}
and in the Main class you define a static helper method:
public class Main {
private static Channel getNewStartTimeChannel(Channel c) {
// parse the string to int
int x = Integer.parseInt(c.getStartTime());
if (x > 100 && x < 500) {
return new Channel(
c.getIndex(),
c.getName(),
// update the int value of the startTime and transform it back to String
"" + (x + 100),
c.getEndTime());
}
return c;
}
you can easily transform the Channels in the original list into the new one:
public static void main(String[] args) {
List<Channel> cList = Arrays.asList(
new Channel(1, "BBC", "0300", "0500"),
new Channel(2, "TR", "0400", "0509"),
new Channel(3, "NEWS", "0700", "0800")
);
List<Channel> cNewList = cList.stream()
.map(Main::getNewStartTimeChannel)
.collect(Collectors.toList());
}

You have to parse the string to integer to do the comparison, so you're good with the parseInt.
Afterwards can always concat your integers with an empty string to get back a string (e.g. 1 + "" will give you a string).

Related

JAVA return longest value if a string contains any of the items from a List

I have the following array of code types:
["sample_code","code","formal_code"]
and the following ids:
String id="123456789_sample_code_xyz";
String id2="91343486_code_zxy";
I want to extract the code type from the ids
this is my code snippet:
String codeTypes[] = {"sample_code","code","formal_code"};
String id= "123456789_sample_code_xyz";
String codeType = Arrays.stream(codeTypes).parallel().filter(id::contains).findAny().get();
System.out.println(codeType);
it doesnt work with the 1st id, because it returns "code" instead of "sample_code", I want to get the longest code type.
for the 1st id the code type should be "sample_code"
for the 2nd id the code type should be "code"
Check for the longest code types first. This means the following changes to your code:
Sort the code types by length descending.
Don’t use a parallel stream. A parallel stream hasn’t got an order. A sequential stream makes sure the code types are checked in order.
Use findFirst(), not findAny() to make sure you get the first match.
So it becomes:
String codeTypes[] = { "sample_code", "code", "formal_code" };
Arrays.sort(codeTypes, Comparator.comparing(String::length).reversed());
String id = "123456789_sample_code_xyz";
Optional<String> codeType = Arrays.stream(codeTypes).filter(id::contains).findFirst();
codeType.ifPresent(System.out::println);
Now output is:
sample_code
You can do it as follows:
public class Main {
public static void main(String[] args) {
String[] ids = { "123456789_sample_code_xyz", "91343486_code_zxy" };
String[] codeTypes = { "sample_code", "code", "formal_code" };
String max;
for (String id : ids) {
max = "";
for (String codeType : codeTypes) {
if (id.contains(codeType)) {
if (max.length() < codeType.length()) {
max = codeType;
}
}
}
System.out.println(id + " : " + max);
}
}
}
Output:
123456789_sample_code_xyz : sample_code
91343486_code_zxy : code
Since you run the strem in parallel, you cannot predict which of the streams finds first a matching pattern. I your case (also in mine when I tried your code snippet) the second stream which looked for "code" was faster, and the whole stream terminates because you just want "findAny()".
Remove the "parallel" and your code works as you expect.
Well, stream API is not suitable for every problem. I think you can use a non-stream version to solve your problem.
I just looped over codeTypes array and for every codeType, have replaced idx with empty string then calculate its length and find min length between idX string and replace.
now if minSize length with replace string length is the same, then it is the candidate for the final result. minSize != id.length() is for when the time that there is not any codeType.
private static String findCodeType(String id, String[] codeTypes) {
int minSize = id.length();
String codeType = "NotFound";
for (String code : codeTypes) {
String replace = id.replaceAll(code, "");
minSize = Integer.min(minSize, replace.length());
if (minSize == replace.length() && minSize != id.length())
codeType = code;
}
return codeType;
}

Sort a list of String with completely custom multiple rules

I have an List of strings like this: [8****, 7****, 73***, ****1, **101, *4101, 12010 etc]
And I want to sort with the following 2 rules.
First rule: Using only the last number / asterisks , the sorted
should be: first asterisks, then numbers 1-9 and then 0.
Second rule: Using the second from last character the sorting should be: first asterisks , then numbers 0-9.
so the final array should become : [7****, 8**** , 73***, 320** , ****1 , **101, 12101]
I have created a custom Comparator and I get each char individually:
public class MyCustomComparator implements Comparator<ObjToCompare> {
#Override
public int compare(ObjToCompare o1, ObjToCompare o2) {
String lastSubstr1 = o1.getMyString.substring(o1.getMyString.length()-1);
String lastSubstr2 = o2.getMyString.substring(o2.getMyString.length()-1);
String secondFromLastSubstr1 =o1.getMyString.substring(o1.getMyString.length()-2,o1.getMyString().length()-1);
String secondFromLastSubstr2 =o2.getMyString.substring(o2.getMyString.length()-2,o2.getMyString().length()-1);
String thirdFromLastSubstr1 = o1.getMyString.substring(o1.getMyString.length()-3,o1.getMyString().length()-2);
String thirdFromLastSubstr2 = o2.getMyString.substring(o2.getMyString.length()-3,o2.getMyString().length()-2);
String fourthFromLastSubstr1 = o1.getMyString.substring(o1.getMyString.length()-4,o1.getMyString().length()-3);
String fourthFromLastSubstr2 = o2.getMyString.substring(o2.getMyString.length()-4,o2.getMyString().length()-3);
String fifthFromLastSubstr1 = o1.getMyString.substring(o1.getMyString.length()-5,o1.getMyString().length()-4);
String fifthFromLastSubstr2 = o2.getMyString.substring(o2.getMyString.length()-5,o2.getMyString().length()-4);
int last = lastSubstr1.compareTo(lastSubstr2);
return lastSubstr1.compareTo(lastSubstr2);
}}
How can I implement the above logic? Thank you very much in advance.
Here's how I would do it: create two Strings (for the two rules). each String holds the characters in the order set by the rule. For example:
String rule1Order = "*1234567890";
now the index of the character in the String can be regarded as numeric order value. the difference between the indexes is the desired compareTo result:
int lastSubstr1Ordervalue = rule1Order.indexOf(lastSubstr1);
int lastSubstr2Ordervalue = rule1Order.indexOf(lastSubstr2);
int lastSubstrCompareTo = lastSubstr1Ordervalue - lastSubstr2Ordervalue;
Here it is the full custom comparator for reference:
public class MyCustomComparator implements Comparator<ObjToCompare> {
//the custom rules
public static final String SORT_ACCORDING_LAST_RULE = "*1234567890";
public static final String SORT_ACCORDING_SECOND_TO_LAST_RULE = "*0123456789";
#Override
public int compare(ObjToCompare o1, ObjToCompare o2) {
//get the last char
String lastSubstr1 = o1.getMyString.substring(o1.getMyString.length()-1);
String lastSubstr2 = o2.getMyString.substring(o2.getMyString.length()-1);
int lastSubstr1stOrderValue = SORT_ACCORDING_LAST_RULE.indexOf(lastSubstr1);
int lastSubstr2ndOrderValue = SORT_ACCORDING_LAST_RULE.indexOf(lastSubstr2);
int lastSubstrCompareTo = lastSubstr1stOrderValue - lastSubstr2ndOrderValue;
if (lastSubstrCompareTo == 0) { //if the last digit is the same, sort with the second to last digit
//get the second from last char
String secondFromLastSubstr1 =o1.getMyString.substring(o1.getMyString.length()-2,o1.getMyString().length()-1);
String secondFromLastSubstr2 =o2.getMyString.substring(o2.getMyString.length()-2,o2.getMyString().length()-1);
int secondFromLastSubstr1stOrderValue = SORT_ACCORDING_SECOND_TO_LAST_RULE.indexOf(secondFromLastSubstr1);
int secondFromLastSubstr2ndOrderValue = SORT_ACCORDING_SECOND_TO_LAST_RULE.indexOf(secondFromLastSubstr2);
return secondFromLastSubstr1stOrderValue - secondFromLastSubstr2ndOrderValue;
} else {
return lastSubstr1stOrderValue - lastSubstr2ndOrderValue;
}
}}

Java Read File Class not creating arraylist

I'm trying to populate an ArrayList with data stored in a text file, the data is 5 different values separated by white space, and a mix of boolean, strings and integers. Also, I'm using BlueJ, not sure if that changes anything though.
When the data is read from the file, objects of type Room should be created based on that data
I am new to Java, I've just started learning it within the last few weeks, my read data class is as follows:
Room Data Class:
public class RoomData
{
//Default Values of a Room
private int roomNumber = 0;
private int bookingNights = 0;
private boolean hasEnSuite = false;
private boolean isBooked = false;
private String bookingName = "<None>";
public void setRoomNumber(int roomNumber)
{
this.roomNumber = roomNumber;
}
public void setBookingNights(int bookingNights)
{
this.bookingNights = bookingNights;
}
public void setHasEnSuite()
{
this.hasEnSuite = hasEnSuite;
}
public void setIsBooked()
{
this.isBooked = isBooked;
}
public void setBookingName()
{
this.bookingName = bookingName;
}
}
ReadDataClass:
public class ReadHotelData
{
private String filePath;
public ReadHotelData()
{
filePath = "hotelData.txt";
}
private List<RoomData> list = new ArrayList <>();
public boolean hasNext() throws FileNotFoundException
{
Scanner s = new Scanner(new File("hotelData.txt"));
while (s.hasNext())
{
String nextLine = s.nextLine(); //reads text file line by line
RoomData roomData = new RoomData();
String[] values = nextLine.split(" "); // splits the text file by white space
roomData.setRoomNumber(Integer.parseInt(values[0]));
roomData.setBookingNights(Integer.parseInt(values[1]));
roomData.setHasEnSuite(Boolean.parseBoolean(values[2]));
roomData.setIsBooked(Boolean.parseBoolean(values[3]));
roomData.setBookingName(String.parseString(values[4]));
list.add(roomData);
}// end loop
s.close();
return true;
}
public List <RoomData> getRoomDataList()
{
return list;
}
}
Like I said I'm new so if I'm missed anything I'd really appreciate any help!
Example of data stored in text file:
0 false David 0 false
0 true John 0 false
0 false Jim 0 true
First create a class RoomData to hold the data for each room and give each variable a meaningful name along with the appropriate type.
Change your arraylist to hold that type instead of String
private List<RoomData> list = new ArrayList<>();
Read each line using s.nextLine()
while(s.hasNext())
{
String nextLine = s.nextLine();
RoomData roomData = new RoomData();
Create an instance of that class, split and parse each value into the corresponding variable in the instance of RoomData you have created.
String[] values = nextLine.split(" ") // split by space
// lets say you have "0 false David 0 false"
// values[0] would be "0"
// values[1] would be "false"
// values[2] would be "David"
// values[3] would be "0"
// values[4] would be "false"
All the values in values would be of type String you will need to convert those from String to the type you have defined in RoomData, for int you can use Integer.parseInt(String s), for boolean there is a similar method (Boolean.parseBoolean(String s))[http://docs.oracle.com/javase/8/docs/api/java/lang/Boolean.html#parseBoolean-java.lang.String-], string values can be set directly.
Add that instance to the arraylist.
list.add(roomData);
} // end of while
Add a getter method to return that list for use in other classes.
public List<RoomData> getRoomDataList() {
return list;
}

How to return multiple values without using Collections?

I am using textbook Murach's java programming, and in one of the exercises, it is asking me to do the following:
add this method (given by the book):
private static String displayMultiple(Displayable d, int count)
write the code for this method so it returns a String that contains the Displayable parameter the number of times specified by the int parameter.
Displayable is an interface that implements getDisplayText(). And this method just returns a String with instance variables of an object, i.e. for an Employee, it returns first name, last name, department, and salary.
Everything works, except for the "returns a String".
This is probably an exercise about loops:
You have a way to convert d to a string: getDisplayText. This yields, say, "ABCD"
You want to return count times that string "ABCD". If count == 3, that means "ABCDABCDABCD".
Useful keywords: for loop, StringBuilder. Here is a template that you can use to get started:
String text = ;// Use getDisplayText here
StringBuilder ret = new StringBuilder();
/* Loop from 0 to count - 1 */ {
// Append `text` to `ret`
}
return ret.toString();
You don't actually need to return multiple values.
As I understand it:
private static String displayMultiple(Displayable d, int count){
String s = "";
String ss = d.getDisplayText();
for(int i=0; i<count; i++){
s += ss;
}
return s;
}
If you want to return multiple values with out using collection then you can create an Class -
public class MultipleValue{
String firstValue;
String secondValue;
//other fields
}
Then from someMethod() where you want to return multiple value (that is firstValue, secondValue) you can do this -
public MultipleValue someMethod(){
MultipleValue mulVal = new MultipleValue();
mulVal.setFirstValue("firstValue");
mulVal.setSecondValue("secondVAlue");
return mulVal;
}
Then from the calling class of someMethod() you can extract multiple values (that is firstValue and secondValue) like this -
//from some calling method
MultipleValue mulVals = someMethod();
String firstValue = mulVals.getFirstValue();
String secondValue = mulVals.getSecondValue();

Adding data to arrayList Java

So I'm creating a logging program where a user enters the KM's and it saves it etc.
I take in four variables - start KM, end KM, start and end location. I'm new to java so I'm just wondering if anyone can confirm if theres a better way to do this. This is my code so far, I want to save it to an array of sorts (to a list??) so I can access each object i.e. the startKM, but they need to be on the same line, as in object 1 of array etc. and then write to file,
What I was thinking of doing was saving that linked list to a file, and adding a ; in the toString method and when reading the file in just breaking it at the ; Is there a better way to do this?? Thanks guys. the data is assigned from whatever the user enters in the text fields.
double startKM;
double endKM;
String startLocation;
String endLocation;
startKM = Double.parseDouble(txtStartKM.getText());
endKM = Double.parseDouble(txtEndKM.getText());
startLocation = txtStartLocation.getText();
endLocation = txtEndLocation.getText();
details.startKM = startKM;
details.endKM = endKM;
details.startLocation = startLocation;
details.endLocation = endLocation;
//List<DrivingDetails> detailsList = new ArrayList<DrivingDetails>();
List detailsList = new ArrayList();
detailsList.add(details);
System.out.println("LinkedList contains = \t " + detailsList.toString());
edit: I have another class (DrivingDetails) which holds the following variables:
public class DrivingDetails {
double startKM;
double endKM;
String startLocation;
String endLocation;
}
Your DrivingDetails class violates the principle of encapsulation for object oriented classes. I would add setters and getters for all properties. Also, you could create a contstructor that handles initialization for you.
public class DrivingDetails {
private double startKM;
private double endKM;
private String startLocation;
private String endLocation;
public DrivingDetails(double startKM, double endKM, String startLocation, String endLocation) {
this.startKM = startKM;
this.endKM = endKM;
this.startLocation = startLocation;
this.endLocation = endLocation;
}
public double getStartKM() {
return startKM;
}
public void setStartKM(double startKM) {
this.startKM = startKM;
}
// rest of the methods left for you ...
}
Your resulting code would then look like:
double startKM;
double endKM;
try {
startKM = Double.parseDouble(txtStartKM.getText());
endKM = Double.parseDouble(txtEndKM.getText());
} catch (NumberFormatException e | NullPointerException e) {
// the line above assumes java 7
// recover
}
DrivingDetails details = new DrivingDetails(startKM, endKM,
txtStartLocation.getText(),
txtEndLocation.getText());
List<DrivingDetails> detailsList = new ArrayList<DrivingDetails>();
detailsList.add(details);
Hope that helps!

Categories