Sorting string array with custom-formatted date - blackberry-jde

I have a string like
String str[]={"jan2011","feb2011","jan2010,"mar2012"};
How do I sort this by Date like: jan2010,jan2011,feb2011,mar2012
thanks for advance(not to use string functions more )

Hoi:
String[] unsorted={"jan2011","feb2011","jan2010","mar2012"};
List<String> unsortedList = Arrays.asList(unsorted);
Collections.sort(unsortedList);
String[] sorted = (String[])unsortedList.toArray();
This should do...

Assuming you have version 6 at your disposal, you can use the built-in
Collections.insertionSort(datavector, comparator);
However:
you'll need to move your strings into a Vector
you'll need to provide a Comparator class for your specific needs
The Comparator class could be something along these lines:
public class DatestringComparator implements Comparator{
public int compare(String s1, String s2) {
// create Date instance based on the content of the input string
Date d1 = ....;
Date d2 = ....;
return d1.compareTo(d2);
}
}

Related

How to filter object lists and create another filtered lists from it

I receive a List of MediaDTO and this Object has two attributes:
String sizeType and String URL.
In 'sizeType' comes the image´s size: small, medium, large, and thumbnail.
So I have to filter the sizeType of these objects and create 4 new lists based on them.
This is how I get the List<MediaDTO> mediaDTO:
medias=[MediaDTO(sizeType=THUMBNAIL, liveloUrl=https://s3.sao01.cloud-object-storage.appdomain.cloud/catalog-media-storage/id-source/productId/skuseller2/thumbnail/celular-iphone-11-azul.png), MediaDTO(sizeType=SMALL, liveloUrl=https://s3.sao01.cloud-object-storage.appdomain.cloud/catalog-media-storage/id-source/productId/skuseller2/small/celular-iphone-11-azul.png), MediaDTO(sizeType=SMALL, liveloUrl=https://s3.sao01.cloud-object-storage.appdomain.cloud/catalog-media-storage/id-source/productId/skuseller2/medium/celular-iphone-11-azul.png), MediaDTO(sizeType=LARGE, liveloUrl=https://s3.sao01.cloud-object-storage.appdomain.cloud/catalog-media-storage/id-source/productId/skuseller2/large/celular-iphone-11-azul.png), MediaDTO(sizeType=THUMBNAIL, liveloUrl=https://s3.sao01.cloud-object-storage.appdomain.cloud/catalog-media-storage/id-source/productId/skuseller2/thumbnail/celular-iphone-11-vermelho.png), MediaDTO(sizeType=SMALL, liveloUrl=https://s3.sao01.cloud-object-storage.appdomain.cloud/catalog-media-storage/id-source/productId/skuseller2/small/celular-iphone-11-vermelho.png), MediaDTO(sizeType=MEDIUM, liveloUrl=https://s3.sao01.cloud-object-storage.appdomain.cloud/catalog-media-storage/id-source/productId/skuseller2/medium/celular-iphone-11-vermelho.png), MediaDTO(sizeType=LARGE, liveloUrl=https://s3.sao01.cloud-object-storage.appdomain.cloud/catalog-media-storage/id-source/productId/skuseller2/large/celular-iphone-11-vermelho.png)]
I achieved filtering for one of the sizes. This works!
However, I could not figure out how can I filter over the 4 sizes and create 4 new lists of it.
If I fix some error another appears ... so I´m really stuck.
And by the way I´ve been searching for a solution on the internet and in the forum for a couple of days but did´nt find something that fits.
If someone might help, I´d really be grateful.
I was thinking about using a 'forEach' to filter but even like that, I could filter just one size.
Thanks in advance.
**This is what I got till now: **
public class ProcessProductDTO {
String processId;
OperationProcess operation;
String categoryId;
ProductDTO productDTO;
}
public class ProductDTO {
String id;
Boolean active;
String displayName;
String longDescription;
List<MediaDTO> medias;
List<AttributeDTO> attributes;
}
public class MediaDTO {
String sizeType;
String liveloUrl;
}
public Properties toOccProductPropertiesDTO(ProcessProductDTO processProductDTO) throws JsonProcessingException {
String pSpecs = convertAttributes(processProductDTO.getProductDTO().getAttributes());
//List<String> medias = convertMedias(processProductDTO.getProductDTO().getMedias());
return Properties.builder()
.id(processProductDTO.getProductDTO().getId()) .active(processProductDTO.getProductDTO().getActive())
.listPrices(new HashMap())
.p_specs(pSpecs)
//.medias(medias)
.displayName(processProductDTO.getProductDTO()
.getDisplayName())
.longDescription(processProductDTO.getProductDTO().getLongDescription())
.build(); }
private String convertAttributes(List<AttributeDTO> attributes) throws JsonProcessingException {
Map<String, String> attribs = attributes.stream()
.collect(Collectors.toMap(AttributeDTO::getName, AttributeDTO::getValue));
return objectMapper.writeValueAsString(attribs);
}
private List<MediaDTO> convertMedias(ProcessProductDTO processProduct, List<MediaDTO> mediaDTO){
List<MediaDTO> filteredList = processProduct.getProductDTO().getMedias();
Set<String> filterSet = mediaDTO.stream().map(MediaDTO::getSizeType).collect(Collectors.toSet());
return filteredList.stream().filter(url -> filterSet.contains("SMALL")).collect(Collectors.toList());
}
UPDATE
I got the following result:
private Properties toOccProductPropertiesDTO(ProcessProductDTO processProductDTO) throws JsonProcessingException {
String pSpecs = convertAttributes(processProductDTO.getProductDTO().getAttributes());
MediaOccDTO medias = convertMedias(processProductDTO.getProductDTO().getMedias());
return Properties.builder()
.id(processProductDTO.getProductDTO().getId())
.active(processProductDTO.getProductDTO().getActive())
.listPrices(new HashMap())
.p_specs(pSpecs)
.medias(medias)
.displayName(processProductDTO.getProductDTO().getDisplayName())
.longDescription(processProductDTO.getProductDTO().getLongDescription())
.build();
}
private MediaOccDTO convertMedias(List<MediaDTO> mediaDTOs){
String smallImageUrls = generateOccUrl(mediaDTOs, ImageSizeType.SMALL);
String mediumImageUrls = generateOccUrl(mediaDTOs, ImageSizeType.MEDIUM);
String largeImageUrls = generateOccUrl(mediaDTOs, ImageSizeType.LARGE);
String thumbImageUrls = generateOccUrl(mediaDTOs, ImageSizeType.THUMB);
return MediaOccDTO.builder()
.p_smallImageUrls(smallImageUrls)
.p_mediumImageUrls(mediumImageUrls)
.p_largeImageUrls(largeImageUrls)
.p_thumbImageUrls(thumbImageUrls)
.build();
}
private String generateOccUrl(List<MediaDTO> mediaDTOs, ImageSizeType imageSizeType){
return mediaDTOs.stream()
.filter(m -> m.getSizeType().equals(imageSizeType))
.map(MediaDTO::getLiveloUrl)
.reduce(",", String::concat);
}
The problem is:
the comparison: m.getSizeType().equals(imageSizeType)
is always false, so the list gets created empty...
Though the question is laborious, I could think of the requirement being, you need to create 4 new lists based on sizeType.
Stream collector, can collect the results to a single data structure. It can be a list, set, Map etc.
Since you need 4 lists based on sizeType, you will need to pass through the stream 4 times to create 4 lists.
Another Alternate will be to create a Map<SizeType, List<MediaDTO>>
This can be achieved through,
mediaDTO.stream().collect(Collectors.toMap(i -> i.getSizeType(), i->i)
I think the toMap doesn't collect the values in a list. We need groupingBy instead.
mediaDTO.stream()
.collect(Collectors.groupingBy(MediaDTO::getSizeType));

Efficient way to group by a given list based on a key and collect in same list java 8

I have the below class:
class A{
String property1;
String property2;
Double property3;
Double property4;
}
So the property1 and property2 is the key.
class Key{
String property1;
String property2;
}
I already have a list of A like below:
List<A> list=new ArrayList<>();
I want to group by using the key and add to another list of A in order to avoid having multiple items with same key in the list:
Function<A, Key> keyFunction= r-> Key.valueOf(r.getProperty1(), r.getProperty2());
But then while doing group by I have to take a sum of property3 and average of property4.
I need an efficient way to do it.
Note: I have skipped the methods of the given classes.
Collecting to a Map is unavoidable since you want to group things. A brute-force way to do that would be :
yourListOfA
.stream()
.collect(Collectors.groupingBy(
x -> new Key(x.getProperty1(), x.getProperty2()),
Collectors.collectingAndThen(Collectors.toList(),
list -> {
double first = list.stream().mapToDouble(A::getProperty3).sum();
// or any other default
double second = list.stream().mapToDouble(A::getProperty4).average().orElse(0D);
A a = list.get(0);
return new A(a.getProperty1(), a.getProperty2(), first, second);
})))
.values();
This could be slightly improved for example in the Collectors.collectingAndThen to only iterate the List once, for that a custom collector would be required. Not that complicated to write one...
Try like this:
Map<A,List<A>> map = aList
.stream()
.collect(Collectors
.groupingBy(item->new A(item.property1,item.property2)));
List<A> result= map.entrySet().stream()
.map(list->new A(list.getValue().get(0).property1,list.getValue().get(0).property1)
.avgProperty4(list.getValue())
.sumProperty3(list.getValue()))
.collect(Collectors.toList());
and create avgProperty4 and sumProperty3 methods like to this
public A sumProperty3(List<A> a){
this.property3 = a.stream().mapToDouble(A::getProperty3).sum();
return this;
}
public A avgProperty4(List<A> a){
this.property4 = a.stream().mapToDouble(A::getProperty4).average().getAsDouble();
return this;
}
result = aList.stream().collect(Collectors
.groupingBy(item -> new A(item.property1, item.property2),
Collectors.collectingAndThen(Collectors.toList(), list ->
new A(list.get(0).property1, list.get(0).property1)
.avgProperty4(list).sumProperty3(list))
)
);

How to convert an object into a map using Java-8

Consider following object:
class Interval {
final String name;
final Date start;
final Date end;
final int intervalId;
}
I am provided with a list of intervals. I need to check it equals a given map.
eg:
boolean checkEqual(List<Interval> intervals, Map<Date, Date> startEnd) {
}
I want to use Java8 to convert list of intervals into a map of start/end dates and then compare with startEndMap
i.e.
boolean checkEqual(List<Interval> intervals, Map<Date, Date> startEnd) {
Map<Date, Date> map = intervals.streams.filter ?? is there a way to do it ?
return map.equals(startEnd)
}
How to do it ?
Is there a better way ?
use the toMap collector:
Map<Date, Date> result = intervals.stream()
.collect(Collectors.toMap(Interval::getStartDate,
Interval::getEndDate));

MVC3/LINQ/EF4.1 selecting distinct col values from a result set?

How can I select a list of column values from a result set (as distinct) and put into a list?
class T {int id; string name;}
-- Controller...
var query = #"exec someStoredProc";
IEnumerable<T> bb =
db2.Database.SqlQuery<T>(query);
// Something like???:
List<string> Names = bb.SelectDistinct("name"); // returns distinct list of names from result set
Since you just need the distinct list of names, you can project to the name property and the just use Distinct() :
List<string> Names = bb.Select( x=> x.name)
.Distinct()
.ToList();
This requires that you make the name property public, also I would rethink your class name T, how about CustomerName (or whatever else is expressive enough so you know what it means) ?
public class CustomerName
{
public int id{get;set;}
public string name {get;set;}
}

Linq to sql truncating string returned by Stored Procedure

I have asked this question before. but i was not able to get any answer. may be i wasnt very clear. let me give some more details.
I have a SP which returns a long string. here is dbml file code
[Function(Name="dbo.spX")]
public ISingleResult<spXResult> spX([Parameter(DbType="VarChar(8000)")] string str)
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), str);
return ((ISingleResult<spXResult>)(result.ReturnValue));
}
and here is spXResult class
public partial class spXResult
{
private string _XML_F52E2B61_18A1_11d1_B105_00805F49916B;
public spXResult()
{ }
[Column(Name="[XML_F52E2B61-18A1-11d1-B105-00805F49916B]",
Storage="_XML_F52E2B61_18A1_11d1_B105_00805F49916B",
DbType="NText", UpdateCheck=UpdateCheck.Never)]
public string XML_F52E2B61_18A1_11d1_B105_00805F49916B
{
get
{
return this._XML_F52E2B61_18A1_11d1_B105_00805F49916B;
}
set
{
if ((this._XML_F52E2B61_18A1_11d1_B105_00805F49916B != value))
{
this._XML_F52E2B61_18A1_11d1_B105_00805F49916B = value;
}
}
}
}
and here is my code
ISingleResult<spXResult> result = ctx.spX("1234");
string returnStr = result.First().XML_F52E2B61_18A1_11d1_B105_00805F49916B;
everything is fine, when the result is not a long string, but as soon as the sp returns a very long string, it truncates the result. i have no clue why.. can someone please help.
thanks
The only thing fishy I can spot is this - here in the declaration, you hvae:
public ISingleResult<spXResult> spX([Parameter(DbType="VarChar(8000)")] string str)
(DbType=VARCHAR(8000)) - which is ANSI (non-Unicode), but then in the column declaration you use NTEXT - first of all, that's UNICODE (2-byte per character), and why NTEXT?? Above you have VARCHAR?
[Column(Name="[XML_F52E2B61-18A1-11d1-B105-00805F49916B]",
Storage="_XML_F52E2B61_18A1_11d1_B105_00805F49916B",
DbType="NText", UpdateCheck=UpdateCheck.Never)]
That seems a bit odd.......
Can you try to make it the same in both places? E.g. VARCHAR(8000) in both cases??
Marc
LinqToSql splits the XML result set into chunks, so you need to run a loop like this:
ISingleResult<spXResult> result = ctx.spX("1234");
string xml = "";
foreach (var x in result)
xml += x.XML_F52E2B61_18A1_11d1_B105_00805F49916B;
Or using LINQ:
string xml = result.Aggregate("", (current, x) => current + x.XML_F52E2B61_18A1_11d1_B105_00805F49916B);
Just change your sp from
SELECT ...
FROM MyTable
FOR XML AUTO
to
DECLARE #ResultXML xml
SET #ResultXML =
(SELECT ...
FROM MyTable
FOR XML AUTO)
SELECT #ResultXML as [MyXML]
and recreate linq method

Resources