I'm probably being stupid here...but I need help with this one! Basically i need to do a .contains("message") to determine if the key already contains the incoming message.
Thanks in advance!
EDIT: Just as a note, i do not want it to do anything if it already exists! Currently its not adding it to the list.
EDIT2: the date will not matter for the incoming message because the incoming message does not have the date portion.
private Map<Integer,List<String>> map = new HashMap<Integer,List<String>>();
public synchronized void addToProblemList(String incomingMessage, int storeNumber){
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy h:mm:ss a");
String formattedDate = sdf.format(date);
if(map.get(storeNumber)==null){
map.put(storeNumber, new ArrayList<String>());
}
for(String lookForText : map.get(storeNumber)){
if(lookForText.contains(incomingMessage)){
}else if(!lookForText.contains(incomingMessage)){
map.get(storeNumber).add(incomingMessage+"\nTime of incident: "+formattedDate+"\n--------------------------------------------------------");
}
}
}
It used to look like this, but it always added it:
public synchronized void addToProblemList(String incomingMessage, int storeNumber){
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy h:mm:ss a");
String formattedDate = sdf.format(date);
if(map.get(storeNumber)==null){
map.put(storeNumber, new ArrayList<String>());
}
if(map.get(storeNumber).contains(incomingMessage)==true){
//Do nothing
}
if (map.get(storeNumber).contains(incomingMessage)==false){
map.get(storeNumber).add(incomingMessage+"\nTime of incident: "+formattedDate+"\n--------------------------------------------------------");
}
What you are adding to the list is a key of the store number and an empty array list,
So the first message for the store you add to the list is empty, therefore your for loop will not execute as it has no elements to iterate.
So add this
if(map.get(storeNumber)==null){
ArrayList<String> aList = new ArrayList<String>();
aList.add(incomingMessage+"\nTime of incident: "+formattedDate+"\n--------------------------------------------------------");
map.put(storeNumber, aList);
}
Note map.get(storeNumber).contains(incomingMessage)==true you dont need to boolean comparison here as contains() returns a boolean.
The reason this original approach of yours wouldn't have worked is doing a List.contains() means you are doing an check to see if the list contains an exact matching string which it would not have since when you have added the String it also contained "\nTime of incident: "+formattedDate+"\n... which I suspect would not have matched just incomingMessage
You have this:
for(String lookForText : map.get(storeNumber)){
if(lookForText.contains(incomingMessage)){
}else if(!lookForText.contains(incomingMessage)){
map.get(storeNumber).add(incomingMessage+"\nTime of incident: "+formattedDate+"\n--------------------------------------------------------");
}
}
Try this instead:
List<String> messages = map.get(storeNumber);
if(!messages.contains(incomingMessage)){
map.get(storeNumber).add(incomingMessage+"\nTime of incident: "+formattedDate+"\n--------------------------------------------------------");
}
Related
what am i doing wrong here, currently xml node in request file coming in, the value 01/22/2020 had to be populated.testers are running new test cases and not populating and it throws an exception.
how can i work to accept empty string.
ParseException: Unparseable date:"".
at java.text.DateFormat.parse
if(stringDate!=null)
You need to add a check for empty also. If it is empty then formatter will not be able to parse it.
if (stringDate != null && !stringDate.isEmpty()) {
if (stringDate.contains("-")) {
format = "yyyy-MM-dd";
} else if (stringDate.contains("/")) {
format = "MM/dd/yyyy";
}
SimpleDateFormat formatter = new SimpleDateFormat(format);
return formatter.parse(stringDate);
} else {
return null;
}
instead of if(stringDate!=null) use StringUtils.isEmpty()
List<String[]> data = Importer.readCsv("test.csv");
A String[] item looks like this:
Position: name (String)
Position: 2017-03-14 18:22:44.149 (String)
What is a good approach in order to sort the list by the timestamp descending? I search for a solution without creating new Objects.
Use Collection.sort() and Comparator.comparing(), I find those easy to read when coming back to it later:
data.sort(Comparator.comparing((String[] o) -> o[1]).reversed());
You can compare the timestamp without conversion, as the format is "correctly" ordering the fields.
If you are confined to Java 7, there will be more boilerplate:
Collections.sort(data, new Comparator<String[]>()
{
#Override
public int compare(String[] o1, String[] o2)
{
return o2[1].compareTo(o1[1]);
// return -o1[1].compareTo(o2[1]);
}
});
Note that I need to compare o2 to o1 in this order or negate the result of comparing o1 to o2 to order the data descending. This becomes much more obvious in the first approach.
Well, thank you very much for your suggestions and impulses.
Special Thanks goes to XtremeBaumer!
Following code does the job too:
List<String[]> data = importer.readCsv(context, csvFile);
Collections.sort(data, new Comparator<String[]>() {
#Override
public int compare(String[] item1, String[] item2) {
String dateString1 = item1[1];
String dateString2 = item2[1];
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Date date1 = null;
Date date2 = null;
try {
date1 = format.parse(dateString1);
date2 = format.parse(dateString2);
} catch (ParseException e) {
e.printStackTrace();
return 0;
}
// dateString1 is an earlier date than dateString2
return date1.compareTo(date2);
}
});
You could use a custom Comparator that takes the second element in each array and converts it to a Timestamp. Note that a Comparator's function can't throw an exception, so you'd have to catch the potential ParseException and deal with it:
Function<String[], Date> parser = s -> {
try {
return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS").parse(s[1]);
} catch (ParseException e) {
return null;
}
};
list.sort(Comparator.comparing(parser));
I have a List of String arrays of the form
List<String[]> currentLoadAddressLocations = new ArrayList<>();
That gets set and parsed through a JSONObject Array
try {
JSONObject dataObject = new JSONObject(data);
JSONArray dataObjArray = dataObject.getJSONArray("stops");
Log.i(TAG, dataObjArray.toString());
for (int i = 0; i < dataObjArray.length(); i++) {
JSONObject addressAndLocation = dataObjArray.getJSONObject(i);
addressGPointJSON.add(addressAndLocation.getString("address"));
locationGPointJSON.add(addressAndLocation.getString("location"));
cityGPointJSON.add(addressAndLocation.getString("city"));
stateGPointJSON.add(addressAndLocation.getString("state"));
fromGPointJSON.add(addressAndLocation.getString("from"));
latGPointJSON.add(reverseGeocoderLatLong(addressGPointJSON.get(i) + ", " + cityGPointJSON.get(i) + ", " + stateGPointJSON.get(0), true));
longGPointJSON.add(reverseGeocoderLatLong(addressGPointJSON.get(i) + ", " + cityGPointJSON.get(i) + ", " + stateGPointJSON.get(0), false));
currentLoadAddressLocations.add(i,
new String[]{
fromGPointJSON.get(i),
addressGPointJSON.get(i),
locationGPointJSON.get(i),
cityGPointJSON.get(i),
stateGPointJSON.get(i),
latGPointJSON.get(i),
longGPointJSON.get(i)
});
} // end of for loop
} // end of try catch block
catch(JSONException e){
e.printStackTrace();
}
Currently, the code gives me back the data structure that I need, a String[] of the form
["2017-03-30 21:00:00", "Address example 123", "Location Example", "CITY", "STATE", "lat", "long"]
repeated depending on how many stops where in the JSON object that was returned. I need to find a way to sort the first value of the array from top to bottom inside the currentLoadAddressLocations array by time, so if one of the dates is "2017-03-30 15:00:00" and the other is "2017-03-30 14:00:00" then the one that is before takes precedence and moves the date to the top of the currenLoadAddressLocations array while at the same time araging the second one to be below. I am having a hard time trying to find a method of doing so. Currently I know that I can compare dates if I parse the dates as:
Date from = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US).parse("2017-03-30 21:00:00");
But do not know how to work around this issue while looping through the currentLoadAddressLocations List. Further more, I do not know how to access the values in order to compare them. I can loop through the selection by using
for(String[] array: currentLoadAddressLocations){
for(String s: array){
Log.i(TAG,"ITEM: " + s);
}
}
But since they are inside a String array they cannot be changed into a date format unless I change them and then parse them back to strings.
Any suggestions will be greatly appreciated.
The answer is you should convert your String[] into a AddressDateLocation class array. Once you do that, it will be much easier to sort you data the way you want
public class AddressDateLocation implements Comparable<AddressDateLocation> {
Date date;
String address;
String location;
public void setDate(Date d) {}
public Date getDate() ...
public void setLocation(String loc) ...
public String getLocation() ...
public void setAddress(String addr) ...
public String getDate() ...
public int compareTo(AddressDateLocation other) ...
}
The data structure you need is likely not an array of String's, unless the order of the pieces ends up in a public API. You'd better keep the information in the native JSONObject, that has Map semantics. Then you can simply order by timestamp with:
List<JSONObject> currentLoadAddressLocations = TODO(/* implement this */);
currentLoadAddressLocations.sort((o1, o2) -> {
return o1.getString("date").compareTo(o2.getString("date"))
});
Note: the date format suggested in the question makes it possible to compare timestamps using their textual representation.
You could make the dates into LocalDateTime objects and use the compareTo method.
I would use the List#sort function like so:
currentLoadAddressLocations.sort((sa1, sa2) -> { // sa = String Array
try {
String pattern = "yyyy-MM-dd HH:mm:ss";
return new SimpleDateFormat(pattern, Locale.US).parse(sa1[0])
.compareTo(new SimpleDateFormat(pattern, Locale.US).parse(sa2[0]));
} catch (ParseException e) {
// If your dates are all valid you shouldn't come here.
e.printStackTrace();
return -1; // move all parse ParseExceptions to the first positions
}
});
I have an Arraylist:
public static ArrayList<ScheduleItem>[] data = (ArrayList<ScheduleItem>[]) new ArrayList[30];
Also, I have an another ArrayList which contain 3 dates:
public static ArrayList<String> dateWay = new ArrayList<String>();
Now, I want to check if a certain day is in the data Arraylist. If not, only then it will parse json file. I tried with this but, It throws null pointer exception
if(!ScheduleItem.data[getPageNumber].get(pageNumber).getDate().equals(ScheduleItem.dateWay.get(pageNumber))){
//method to parse json
}
ArrayList<ScheduleItem> data = new ArrayList<ScheduleItem>();
Date date = new Date(); //set your date
for(ScheduleItem item: data){
if(date.equals(item.getDate()){
System.out.println("Contains the date");
}
}
I have an array of valid date formats I want to detect in a some text a user enters:
public static final DateFormat[] DATE_FORMATS = {
new SimpleDateFormat("M/d/yy"),
new SimpleDateFormat("M.d.yy"),
new SimpleDateFormat("M-d-yy"),
new SimpleDateFormat("M/d/yyyy"),
new SimpleDateFormat("M.d.yyyy"),
new SimpleDateFormat("M-d-yyyy"),
new SimpleDateFormat("M/dd/yy"),
new SimpleDateFormat("M.dd.yy"),
new SimpleDateFormat("M-dd-yy"),
new SimpleDateFormat("M/dd/yyyy"),
new SimpleDateFormat("M.dd.yyyy"),
new SimpleDateFormat("M-dd-yyyy"),
new SimpleDateFormat("MM/d/yy"),
new SimpleDateFormat("MM.d.yy"),
new SimpleDateFormat("MM-d-yy"),
new SimpleDateFormat("MM/d/yyyy"),
new SimpleDateFormat("MM.d.yyyy"),
new SimpleDateFormat("MM-d-yyyy"),
new SimpleDateFormat("MM/dd/yy"),
new SimpleDateFormat("MM.dd.yy"),
new SimpleDateFormat("MM-dd-yy"),
new SimpleDateFormat("MM/dd/yyyy"),
new SimpleDateFormat("MM.dd.yyyy"),
new SimpleDateFormat("MM-dd-yyyy"),
new SimpleDateFormat("yyyy/MM/dd"),
new SimpleDateFormat("yyyy.MM.dd"),
new SimpleDateFormat("yyyy-MM-dd")
};
Dates are detected through the code below. this.searchTokens is an array of each search term from the user's entered text.
List<Date> datesFound = new ArrayList<Date>();
for (String token : this.searchTokens) {
Date date;
for (DateFormat dateFormat : DateHelper.DATE_FORMATS) {
try {
// Attempt to parse this token as a date.
date = (Date) dateFormat.parse(token);
datesFound.add(date);
break;
} catch (ParseException e) {
continue;
}
}
}
This code validates and adds the correct dates to my List object for any date except dates formatted like so:
yyyy/MM/dd
yyyy.MM.dd
yyyy-MM-dd
In one of my unit tests, the dates 2010/08/15 and 2011/08/15 match to M/d/yy the first time through the loop and become Date objects with the values Jun 8, 2182 and Jul 8, 2182, respectively. Why would the first SimpleDateFormat in DATE_FORMATS accept a match like this? The number of digits don't even match up... Is there a better way I should go about detecting these dates?
Call .setLenient(false) on the SimpleDateFormat object you created.
I think M and MM will still both match 1 or 2 digits though. I think you would have to check that yourself (with a regex) if that's not what you want.
This worked for me. Using .setLenient(false) by itself did not fix the problem.
for(int i=0; i < PropDateFormats.length; i++)
{
try
{
ParsePosition p = new ParsePosition(0);
PropDateFormats[i].setLenient(false);
PropagationDate = PropDateFormats[i].parse(_date,p);
if(p.getIndex() < _date.length())
{
log.trace("setPropagationDate.parse("+_date+") failed. Index=["+i+"[ as"+PropagationDate);
throw new ParseException(_date, p.getIndex());
}
log.trace("setPropagationDate.parse("+_date+") passed. Index=["+i+"[ as"+PropagationDate);
break;
}