I am new to java I want to optimize my code using Map in java. When I
write my Code I use lot of if else statement so I want reduce my code
using map of collection framework When I implement Map i am not get
accurate result. My Function totally not working. Here Is my code.
private List<Item> getBussinessSearchItem(IteamSearch itemSearch, byte searchType,int size, int offSet){
StringBuilder queryBuilder - new StringBuilder();
if(itemSearch.getOrigin()!=null && (checkOriginDomain(itemSearch.getOrigin))) {
if(itemSearch.getSort().equalsIgnoreCase("name")) {
if(itemSearch.getSortOrder() == 1) {
queryBuilder.append("ORDDER BY Name ASc");
}else {
queryBuilder.append("ORDDER BY Name ASc");
}
}else if(itemSearch.getSort().equalsIgnoreCase("upc1")) {
if(itemSearch.getSortOrder() == 1) {
queryBuilder.append("ORDDER BY upc1 ASc");
}else {
queryBuilder.append("ORDDER BY upc1 ASc");
}
}
else if(itemSearch.getSort().equalsIgnoreCase("minQuantiy")) {
if(itemSearch.getSortOrder() == 1) {
queryBuilder.append("ORDDER BY minQuantiy ASc");
}else {
queryBuilder.append("ORDDER BY minQuantiy ASc");
}
}
}
when I use this above statement it works fine and give me result
properly sorting with ASCENDING AND DESCINDING order. But I do not
want to implement above statement I want to implement map and that map
works same as the above statement.
Here is my code but this below code not working
private Map<String , String> getBussinessSearchItem(ItemSearch itemSearch){
Map<Srring,String> newMap = new HashMap<>();
itemSearch.getSort().equalsIgnoreCase("name");
itemSearch.getSort().equalsIgnoreCase("upc1");
itemSearch.getSort().equalsIgnoreCase("minQuantiy");
}
I do not know how to implement map instead of if else statement. I
want solve this issue using map or enum.
My ItemSerach table contain name,upc1,minquantity
If you move sort options to a separate class ItemSearchOrder class which implements equals and hashCode properly, you could use it directly as key in your map:
class ItemSearchOrder {
private final String sort;
private final int order;
public ItemSearchOrder(final String sort, final int order) {
this.sort = Objects.requireNonNull(sort);
this.order = order;
}
public static ItemSearchOrder asc(final String sort) {
return new ItemSearchOrder(sort, 1);
}
public static ItemSearchOrder desc(final String sort) {
return new ItemSearchOrder(sort, 0);
}
#Override
public boolean equals(final Object other) {
if (other == null) return false;
if (other == this) return true;
if (other.getClass() != this.getClass()) return false;
return this.order == other.order
&& this.sort.equalsIgnoreCase(other.sort);
}
#Override
public int hashCode() {
return Objects.hash(sort, order);
}
}
Then build your map:
final Map<ItemSearchOrder, String> sortQueries = Map.ofEntries(
Map.entry(ItemSearchOrder.asc("name")), "ORDER BY name ASC"),
Map.entry(ItemSearchOrder.desc("name")), "ORDER BY name DESC"),
Map.entry(ItemSearchOrder.asc("upc1")), "ORDER BY upc1 ASC"),
...
);
And then use it to look up the correct ORDER BY clause:
public List<Item> getBussinessSearchItem(
final IteamSearch itemSearch, ...) {
final String sort = sortQueries.get(itemSearch.getOrder());
if (sort == null) {
// unknown sort
}
// ...
}
Related
I'm writing a function to check multiple conditions in an array, if they are all true then return true.
For example:
public class Attribute {
private final String key;
private final String value;
//...
}
boolean canContactDogOwner(List<Attribute> attributes) {
boolean hasDog = false;
boolean isSubscribed = false;
boolean isOkToCall = false;
for (var attribute : attributes) {
if (attribute.key().equals("dogName")) {
hasDog = true;
} else if (attribute.key().equals("isSubscribed") && attribute.value().equals("Y")) {
isSubscribed = true;
} else if (attribute.key().equals("okToCall") && attribute.value().equals("Y")) {
isOkToCall = true;
}
// 1.
}
return hasDog && isSubscribed && isOkToCall;
}
void foo() {
List<Attribute> attributes = new ArrayList<>();
attributes.add(new Attribute("isSubscribed", "Y"));
attributes.add(new Attribute("okToCall", "Y"));
attributes.add(new Attribute("mobile", "12345678"));
attributes.add(new Attribute("landline", "1346346"));
attributes.add(new Attribute("email", "white#email.com"));
attributes.add(new Attribute("dogName", "Alex"));
boolean canContact = canContactDogOwner(attributes);
}
Two questions:
When all conditions are meet, the loop can be break, but if I add a check there, we would be checking every step in the loop, which doesn't look good. Any suggestions?
Is there a better / concise way to do it?
Like following?
boolean canContactDogOwner(List<Attribute> attributes) {
return attributes.stream().allMatch(A,B,C);
}
You can modify method canContactDogOwner to be like this,
boolean canContactDogOwner(List<Attribute> attributes) {
List<Attribute> conditions = new ArrayList<>();
conditions.add(new Attribute("isSubscribed", "Y"));
conditions.add(new Attribute("okToCall", "Y"));
return attributes.containsAll(conditions) &&
attributes.stream().anyMatch((attribute -> attribute.key.equals("dogName")));
}
A working and cleaner approach (IMO) will be to use some abstract data type like Map in this case..
static boolean canContactDogOwner(List<Attribute> attributes){
Map<String, String> attributeMap = new HashMap<>(); // empty map
attributes.forEach(attr -> attributeMap.put(attr.getKey(), attr.getValue())); // populate map
return attributeMap.containsKey("dogName") &&
"Y".equals(attributeMap.get("isSubscribed")) &&
"Y".equals(attributeMap.get("okToCall")); // Constant-String-first on equals check to avoid nullPointerExc with less code, yet clean
}
The code above with the comment is self-explanatory, so not adding details of the code.
But it is worth mentioning that
the complexity is still O(n) like other solutions here, n - number of elements (attribute objects)
flexibility to add or remove more conditions in the return statement
map as a chosen data-type and <Constant>.equals check avoids key validation and nullPointerException respectively.
If you are fascinated with Java-Streams, you can modify the code like this too..
static boolean canContactDogOwner(List<Attribute> attributes){
Map<String, String> attributeMap = attributes.stream()
.collect(Collectors.toMap(Attribute::getKey, Attribute::getValue));
return attributeMap.containsKey("dogName") &&
"Y".equals(attributeMap.get("isSubscribed")) &&
"Y".equals(attributeMap.get("okToCall"));
}
You could check if all condition is meet only when you set a value to true,
it will happen only 3 time.
And more concise way, probably with stream().anyMatch() but i'm not sure it will be more readable
Stream and allMatch(Predicate predicate) is a better way to do it in my opinion, but keep in mind that allMatch() take a Predicate as an argument, so you need to provide one.
I would suggest you encapsulate the attributes and create a class
something like Owner.
public class Owner {
private boolean isSubscribed;
private boolean okToCall;
private String mobile;
private String landline;
private String email;
private Optional<String> dogName;
public Owner(boolean isSubscribed, boolean okToCall, String mobile, String landline, String email, Optional<String> dogName) {
this.isSubscribed = isSubscribed;
this.okToCall = okToCall;
this.mobile = mobile;
this.landline = landline;
this.email = email;
this.dogName = dogName;
}
public boolean canContact() {
return this.isSubscribed && this.okToCall;
}
public boolean hasDog() {
return dogName.isPresent();
}
}
This way you do not have to deal with the if loops, the Owner object will say if they have a dog and can be contacted, etc.
public static void main(String[] args) {
Owner owner = new Owner(true, true, "12345678", "1346346", "white#email.com", Optional.of("Alex"));
boolean canContact = owner.hasDog() && owner.canContact();
}
I think you can have two lists of your conditions and attributes and then check whether attributes contain all condition or not.
public static Boolean allConditionsExist(List<String> attributes, List<String> conditions) {
return attributes.containsAll(conditions);
}
To convert your conditions and attributes to a list you can do something like this.
List<String> conditions = Arrays.asList("dogName","isSubscribed", "okToCall"); // add all your conditions
and
List<String> attributeKeys = attributes.stream().map(Attribute::getKey).collect(Collectors.toList());
Then call
allConditionExist(attributeKeys, conditions);
Assuming that every attribute is present only once, you could write
boolean canContactDogOwner(List<Attribute> attributes) {
int matches = 0;
for (var attribute : attributes) {
if (attribute.key().equals("dogName")) ||
attribute.key().equals("isSubscribed") && attribute.value().equals("Y") ||
attribute.key().equals("okToCall") && attribute.value().equals("Y"))
{
matches++;
if (matches >= 3) {
return true;
}
}
}
return false;
}
For the stream way you could write a Collector, constructed with a list of Predicates and returning a boolean. Wouldn't be the fastest...
Something like:
public class AllMatch<T> implements Collector<T, Set<Predicate<T>>, Boolean>
{
private Set<Predicate<T>> filter;
public AllMatch(Predicate<T>... filter)
{
super();
this.filter = new HashSet(Arrays.asList(filter));
}
#Override
public Supplier<Set<Predicate<T>>> supplier()
{
return () -> new HashSet<>();
}
#Override
public BinaryOperator<Set<Predicate<T>>> combiner()
{
return this::combiner;
}
#Override
public Set<Characteristics> characteristics()
{
return Stream.of(Characteristics.UNORDERED).collect(Collectors.toCollection(HashSet::new));
}
public Set<Predicate<T>> combiner(Set<Predicate<T>> left, Set<Predicate<T>> right)
{
left.addAll(right);
return left;
}
public Set<Predicate<T>> accumulator(Set<Predicate<T>> acc, T t)
{
filter.stream().filter(f -> f.test(t)).forEach(f ->
{
acc.add(f);
});
return acc;
}
#Override
public Function<Set<Predicate<T>>, Boolean> finisher()
{
return (s) -> s.equals(filter);
}
#Override
public BiConsumer<Set<Predicate<T>>, T> accumulator()
{
return this::accumulator;
}
public static void main(String[] args) {
Integer[] numbers = {1,2,3,4,5,6,7,8};
System.out.println(Arrays.stream(numbers).collect(new AllMatch<Integer>((i)-> i.equals(5),(i)-> i.equals(6))));
System.out.println(Arrays.stream(numbers).collect(new AllMatch<Integer>((i)-> i.equals(5),(i)-> i.equals(9))));
}
}
I have a code-base where I am trying to determine similarities between offered services. These services have categories. However, I want to determine likeness by comparing the set of categories, the time it takes to do the service, and the amount the service costs. I have written the code, and it's working as expected (I think), but I get the sense I am missing something, so I wanted to put it here to get some feedback, and gain some understanding.
Test
#Test
public void testSimilarProjectComparatorSorting() {
List<ProjectService> projectServices = createProjectServices();
System.out.println(projectServices);
projectServices.sort(new SimilarProjectComparator());
System.out.println(projectServices);
// Assertions
}
public static List<ProjectService> createProjectServices() {
List<ProjectService> projectServices = new ArrayList<>();
ProjectService projectService = new ProjectService();
projectService.setAmount(new BigDecimal(1800));
projectService.setDifficultyScale(Estimation.FIVE);
Category genericCat = new Category();
genericCat.setName("Generic");
genericCat.setSlug("generic");
Category listingCat = new Category();
listingCat.setName("Listing");
listingCat.setSlug("listing");
Category webCat = new Category();
webCat.setName("Web");
webCat.setSlug("web");
projectService.setCategories(new HashSet<>(Arrays.asList(genericCat, listingCat, webCat)));
projectServices.add(projectService);
projectService = new ProjectService();
projectService.setAmount(new BigDecimal(800));
projectService.setDifficultyScale(Estimation.THREE);
Category outliningCat = new Category();
outliningCat.setName("Outlining");
outliningCat.setSlug("outlining");
Category bullHeadedCat = new Category();
bullHeadedCat.setName("Bull-Headed");
bullHeadedCat.setSlug("bull-headed");
projectService.setCategories(
new HashSet<>(
Arrays.asList(
outliningCat,
bullHeadedCat,
webCat
)
)
);
projectServices.add(projectService);
projectService = new ProjectService();
projectService.setAmount(new BigDecimal(1500));
projectService.setDifficultyScale(Estimation.FIVE);
Category writingCat = new Category();
writingCat.setName("Writing");
writingCat.setSlug("writing");
projectService.setCategories(
new HashSet<>(
Arrays.asList(
writingCat,
genericCat,
listingCat
)
)
);
projectServices.add(projectService);
projectService = new ProjectService();
projectService.setAmount(new BigDecimal(1400));
projectService.setDifficultyScale(Estimation.TWO);
projectService.setCategories(
new HashSet<>(
Arrays.asList(
writingCat,
genericCat,
listingCat,
webCat
)
)
);
projectServices.add(projectService);
return projectServices;
}
Code
public class SimilarProjectComparator implements Comparator<ProjectService> {
#Override
public int compare(ProjectService o1, ProjectService o2) {
Set<Category> o1CategorySet = o1.getCategories();
Set<Category> o2CategorySet = o2.getCategories();
Integer categoryMatch = 0;
Double matchQuality = 0.0;
if (o1CategorySet != null && o2CategorySet != null) {
for (Category o1Category : o1CategorySet) {
for (Category o2Category : o2CategorySet) {
Integer match = o1Category.getName().compareTo(o2Category.getName());
if (match > 0) {
categoryMatch++;
} else {
categoryMatch--;
}
}
}
}
if (categoryMatch > 0) {
matchQuality++;
} else {
matchQuality--;
}
Integer scaleMatch = o1.getDifficultyScale().getEstimation().compareTo(
o2.getDifficultyScale().getEstimation()
);
if (scaleMatch > 0) {
matchQuality++;
} else {
matchQuality--;
}
Integer amountMatch = o1.getAmount().compareTo(o2.getAmount());
if (amountMatch > 0) {
matchQuality++;
} else {
matchQuality--;
}
return matchQuality.intValue();
}
}
I would assume the order would be (judging by how similar the categories are): 1400, 1500, 800, then 1800. However, the actual order is: 800, 1400, 1500, 1800. I am new to comparators, and am not sure I am doing this right. Is there something I'm missing or is this working correctly, and it's my assumptions that are incorrect? I understand that I am trying to determine the quality of the object match using 3 different props, so how similar the categories are doesn't guarantee the order I mentioned above, unless it held more weight. Which I don't think is necessary from a business logic standpoint. I am just new to comparators, and trying to understand this. Thanks for any help ahead of time!
You are looking for similarities. If comparing two elements results in 0 than those elements are identical. Otherwise they are not. I changed your routine to:
public int compare(ProjectService o1, ProjectService o2) {
Set<Category> o1CategorySet = o1.getCategories();
Set<Category> o2CategorySet = o2.getCategories();
int categoryMatch = 0;
double matchQuality = 0.0;
if ((o1CategorySet != null) && (o2CategorySet != null)) {
for (Category o1Category : o1CategorySet) {
for (Category o2Category : o2CategorySet) {
int match = o1Category.getName().compareTo(o2Category.getName());
if (match == 0) {
categoryMatch++;
} else {
categoryMatch--;
}
}
}
}
if (categoryMatch == 0) {
matchQuality++;
} else {
matchQuality--;
}
int scaleMatch = o1.getDifficultyScale().getEstimation().compareTo(o2.getDifficultyScale().getEstimation());
if (scaleMatch == 0) {
matchQuality++;
} else {
matchQuality--;
}
int amountMatch = o1.getAmount().compareTo(o2.getAmount());
if (amountMatch == 0) {
matchQuality++;
} else {
matchQuality--;
}
return (int) matchQuality;
}
With that the sorting should be working.
I have below table
question_text_id question_id language_id question_text
2 7 1 english_text_1
3 7 2 spanish_text_1
4 8 2 spanish_text_2
5 8 1 english_text_2
NOw i want to create list for each distinct question_id
i have used below code
List<QuestionText> questionTextList = questionManager.getQuestionsTextByQuestionId(Long.parseLong(questions.getQuestionId().toString()));
for (QuestionText questionText : questionTextList) {
questionMap.put("questionId", questionText.getQuestionId());
questionMap.put("language", questionText.getLanguageId());
if(questionText.getLanguageId().longValue() == 1){
questionMap.put("englishQuestionText",questionText.getQuestionText());
} else {
questionMap.put("spanishQuestionText",questionText.getQuestionText());
}
questionListMap.add(questionMap);
}
adminCollectionBookendModel.put("questionListMap",questionListMap);
[{questionId = 1,language=1, englishQuestionText = english_text_1,spanishQuestionText=spanish_text_1},{questionId = 1,language=2, englishQuestionText = english_text_1,spanishQuestionText=spanish_text_1}]
But this give me repeatetion of object of same data if i have both spanish and english question text as shown above. How to get unique list?
How to get both spanish text and english text for each question_id along with language_id and to access it?
Please help me on this
The first step would be to create a POJO Class like this,
public class QuestionDetails {
private int questionId;
private int englishLanguageId;
private int spanishLanguageId;
private String englishLanguageText;
private String spanishLanguageText;
public int getQuestionId() {
return questionId;
}
public void setQuestionId(int questionId) {
this.questionId = questionId;
}
public int getEnglishLanguageId() {
return englishLanguageId;
}
public void setEnglishLanguageId(int englishLanguageId) {
this.englishLanguageId = englishLanguageId;
}
public int getSpanishLanguageId() {
return spanishLanguageId;
}
public void setSpanishLanguageId(int spanishLanguageId) {
this.spanishLanguageId = spanishLanguageId;
}
public String getEnglishLanguageText() {
return englishLanguageText;
}
public void setEnglishLanguageText(String englishLanguageText) {
this.englishLanguageText = englishLanguageText;
}
public String getSpanishLanguageText() {
return spanishLanguageText;
}
public void setSpanishLanguageText(String spanishLanguageText) {
this.spanishLanguageText = spanishLanguageText;
}
#Override
public String toString() {
return new StringBuilder().append("questionId: ").append(questionId)
.append(" ,englishLanguageId: ").append(englishLanguageId)
.append(" ,englishLanguageText: ").append(englishLanguageText)
.append(" ,spanishLanguageId: ").append(spanishLanguageId)
.append(" ,spanishLanguageText: ").append(spanishLanguageText)
.toString();
}
}
Next step would be to change your code snippet like this:
List<QuestionDetails> questionsList = new ArrayList<>();
List<QuestionText> questionTextList = questionManager
.getQuestionsTextByQuestionId(Long.parseLong(questions
.getQuestionId().toString()));
for (QuestionText questionText : questionTextList) {
/* Get QuestionDetails Object */
QuestionDetails qd = getQuestionDetails(
questionText.getQuestionId(), questionsList);
/* Check Null */
if(null == qd) {
/* Get New Object */
qd = new QuestionDetails();
/* Add Object To List */
questionsList.add(qd);
}
/* Set Question ID */
qd.setQuestionId(questionText.getQuestionId());
/* Set Language ID & Text */
if (questionText.getLanguageId().longValue() == 1) {
qd.setEnglishLanguageId(questionText.getLanguageId()
.longValue());
qd.setEnglishLanguageText(questionText.getQuestionText());
} else {
qd.setSpanishLanguageId(questionText.getLanguageId()
.longValue());
qd.setSpanishLanguageText(questionText.getQuestionText());
}
}
adminCollectionBookendModel.put("questionListMap", questionsList);
Finally, here is the implementation of the getQuestionDetails function:
private QuestionDetails getQuestionDetails(int questionId,
List<QuestionDetails> questionsList) {
/* Search Existing Object */
for (QuestionDetails qd : questionsList) {
/* Match Found */
if (qd.getQuestionId() == questionId) {
return qd;
}
}
/* No Object Found */
return null;
}
I would recommend doing the following:
To distinguish QuestionText, you need to override equals method using question_text_id. Otherwise two questions with the same question_id, but different language texts would be equal.
Then create two separate maps for each language. Then just iterate throug all questions and put each question in a corresponding map by question_id. You can retrive a question object by its question_id and get all necessary fields from it, including spanish / english text
List<QuestionText> questionTextList = questionManager.getQuestionsTextByQuestionId(Long.parseLong(questions.getQuestionTextId().toString()));
for (QuestionText questionText : questionTextList) {
if(questionText.getLanguageId().longValue() == 1){
englishQuestionMap.put("question_id",questionText);
} else {
spanishQuestionMap.put("question_id",questionText);
}
questionListMap.add(questionMap);
}
So, your maps will have type of Map<Long, QuestionText>
I have an Item object having 4 String fields and 3 boolean fields.
I have to construct this object based on the 3 boolean variables.
The target is whenever any one of the boolean variable is true we have to create the object having that/those boolean variable set.
If for any situation none of the boolean variables are true, we wont create the object.
I am using a COR to check whether any of the boolean fields will be set or not based on some business logic.
I was trying this with builder, but then I have to construct so many objects and later discard them when none of the boolean variables found true.
Can anyone have any better idea, to solve this kind of problem ?
Well thanks for the 2 delete flag for this question. Thank for the thoughts on this question as well.
I did something to achieve what I want. Which is quite flexible I believe. Only part if there is a dependency on If loop, but that is acceptable since Report class can have extra boolean so when that class is changed, it's builder should be touched to cater that change. Rest this is flexible which I wanted.
public class Report {
private String acftNo;
private Date plannedDate;
private String plannedStn;
private Integer mntncId;
private Set<String> capableStations;
private String routedStn;
private boolean isRoutedNEQPlannedStn; //Inconsistency type 1
private boolean isCapableAtPlannedStn; //Inconsistency type 2
private boolean isPlannedOrRoutedStationExists; //Inconsistency type 3/5
public Report(String acftNo, Integer mntncId) {
super();
this.acftNo = acftNo;
this.mntncId = mntncId;
}
public Report(String acftNo, Date plannedDate, String plannedStn,
Integer mntncId) {
super();
this.acftNo = acftNo;
this.plannedDate = plannedDate;
this.plannedStn = plannedStn;
this.mntncId = mntncId;
}
//setters and getters. Removed for space.
public static Report buildReport(Maintenance<?> task, Set<InconsistencyReport> enumSet) {
Report temp = new Report(task.getAssignment().getAircraftNumber(),task.getAssignment().getMntncScheduleDate(),
task.getAssignment().getStationCode(),task.getAssignment().getMntncId());
temp.setCapableStations(InconsistencyReport.getCapableStations(task));
for(InconsistencyReport ir : enumSet)
{
if(ir.compareTo(InconsistencyReport.ROUTED_STN_NEQ_PLANNED_STN)==0)
temp.setRoutedNEQPlannedStn(true);
if(ir.compareTo(InconsistencyReport.ITEM_NT_CAPABLE_AT_PLANNED_STN)==0)
temp.setCapableAtPlannedStn(true);
if(ir.compareTo(InconsistencyReport.NO_ROUTD_STN_ON_A_DATE)==0)
temp.setPlannedOrRoutedStationExists(true);
}
return temp;
}
}
calculateInconsitencyReport() method which will decide whether to create object or not.
public class InconsistencyReportChain {
public enum InconsistencyReport implements InconsistencyReportIface {
ROUTED_STN_NEQ_PLANNED_STN {
#Override
public boolean findInconsistency(Maintenance<?> task ) {
if(!validate(task))
return false;
//some logic
return true;
return false;
}
},
ITEM_NT_CAPABLE_AT_PLANNED_STN {
#Override
public boolean findInconsistency(Maintenance<?> task) {
if(!validate(task))
return false;
//some logic
return true;
return false;
}
},
NO_ROUTD_STN_ON_A_DATE {
#Override
public boolean findInconsistency(Maintenance<?> task) {
if(!validate(task))
return false;
//some logic
return true
return false;
}
};
#Override
public boolean validate(Maintenance<?> task) {
return !(null == task.getAssignment());
}
static Set<String> getCapableStations(Maintenance<?> task)
{
Set<String> capableStations = newHashSet();
if(task.getCapStationList() != null)
{
capableStations.addAll(Arrays.asList(task.getCapStationList().split(StringConstants.COMMA_SPLIT_REGEX)));
}
if(task.getCapStationClassList() != null)
{
Map<String, List<String>> stationClassMap = CacheManager.get(STN_CLASS.name());
List<String> stationClass = Arrays.asList(task.getCapStationClassList().split(StringConstants.COMMA_SPLIT_REGEX));
for(String stnClass : stationClass)
{
capableStations.addAll(stationClassMap.get(stnClass));
}
}
return capableStations;
}
}
public static Report calculateInconsitencyReport(Maintenance<?> task) {
Set<InconsistencyReport> enumSet = null;
for(InconsistencyReport iReport : InconsistencyReport.values())
{
if(iReport.findInconsistency(task))
{
if(null==enumSet)
enumSet = EnumSet.of(iReport);
else
enumSet.add(iReport);
}
}
if(null!= enumSet && enumSet.size() > 0)
return Report.buildReport(task,enumSet);
return null;
}
}
Helper Interface:
public interface InconsistencyReportIface {
public boolean findInconsistency(Maintenance<?> task );
public boolean validate(Maintenance<?> task );
}
Details of class logic is teared off because of security.
What is the problem? Just create your object when one of your booleans is true.
if(bool1 || bool2 || bool3) {
item = new Item(str1, str2, str3, str4, bool1, bool2, bool3);
}
From what I understand of your description:
a) you will have some bools that will determine wether you create a certain object or not.
b) you may have to include some more bools into the "check protocol"
c) you have to do this checking in a loop where
i/ you check for the bool variable
ii/ you check if the object had been created previously
I still don't quite get it yet, but.. that looks pretty straight forward to me. Let's say your bools are stored in a boolean array boolean[] bools and your strings in a string array String[] strings (which, btw, I don't know what they are used for). You are saying to check if every bool is true and then create an object based on that result.
boolean[] bools = new boolean[] { ... };
String[] strings = new String[] { ... };
boolean checks = false;
for(int i = 0; i<bools.length && !checks; i++)
checks = bools[i];
//so far we will have processed if any of the bools was false, which was your condition
if(checks)
Object object = new Object(); //create your desired object
I don't understand why you would need to check if the object has been constructed previously, though, so I didn't include it in my suggestion :P
context :
i'm working on an applet witch manage fidelity cards. past version of the app had been done by an other developper. there is no documentation. i have to improve it.
problem :
to reach a customer, the app have some combobox. those combobox are filled by vertors
i try to sort item in the combobox but fail each times
i've read things about Collections.sort(x); where x could be a List or a Vector
but wherever i put the instruction for sorting elements, eclipse mark sort with this error :
Bound mismatch: The generic method sort(List<T>) of type Collections is not applicable for the arguments (Vector<NomClient>). The inferred type NomClient is not a valid substitute for the bounded parameter <T extends Comparable<? super T>>
here is the code of the combobox :
private JComboBox<Object> getComboBox() {
if (this.comboBox == null) {
this.comboBox = new JComboBox<Object>();
this.comboBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
try {
SelectionNumeroCarteFidelite2.this.name = SelectionNumeroCarteFidelite2.this.comboBox
.getSelectedItem().toString();
SelectionNumeroCarteFidelite2.this.mod2 = new DefaultComboBoxModel<Object>(
Select.listePrenomclientfidelite(SelectionNumeroCarteFidelite2.this.name));
SelectionNumeroCarteFidelite2.this.comboBox_1
.setModel(SelectionNumeroCarteFidelite2.this.mod2);
SelectionNumeroCarteFidelite2.this.lblTaperOuSlectionner
.setVisible(false);
} catch (final Exception e1) {
final String message = "Choix Impossible - Merci de vérifier votre sélection";
System.out.print("Nom " + message);
final AlerteSelection fenetre = new AlerteSelection(
SelectionNumeroCarteFidelite2.this.interfaceactuelle,
message);
fenetre.setVisible(true);
SelectionNumeroCarteFidelite2.this.interfaceactuelle
.setEnabled(false);
SelectionNumeroCarteFidelite2.this.lblValider
.setVisible(false);
SelectionNumeroCarteFidelite2.this.lblTaperOuSlectionner
.setVisible(true);
}
}
});
this.comboBox.setEnabled(false);
this.comboBox.setForeground(Color.GRAY);
this.comboBox.setFont(new Font("Tahoma", Font.BOLD, 11));
this.comboBox.setEditable(true);
this.comboBox.setBorder(null);
this.comboBox.setBackground(Color.WHITE);
this.comboBox.setBounds(528, 426, 278, 22);
this.mod = new DefaultComboBoxModel<Object>(
Select.listenomclientfidelite());
this.comboBox.setModel(this.mod);
AutoCompletion.enable(this.comboBox);
}
return this.comboBox;
}
here is the code of the Select.listenomclientfidelite()
public static Object[] listenomclientfidelite() {
final Vector<NomClient> requete = new Vector<NomClient>();
try {
c = Connexion.getCon();
final String sql = "SELECT DISTINCT NOMCLIENT FROM CARTE_DE_FIDELITE INNER JOIN CLIENT ON CLIENT.IDCLIENT=CARTE_DE_FIDELITE.IDCLIENT";
preStm = c.prepareStatement(sql);
rs = preStm.executeQuery();
} catch (final Exception e) {
System.out.print("erreur" + e.getMessage());
}
try {
requete.add(null);
NomClient liste;
while (rs.next()) {
liste = new NomClient();
liste.setNom(rs.getString(1));
requete.add(liste);
System.out.println("listenomclientfidelite, liste is : "+liste);
}
rs.close();
preStm.close();
} catch (final Exception e) {
System.out.print("errorlistenom" + e.getMessage());
}
return requete.toArray(new Object[0]);
After beeing advised by Hovercraft Full Of Eels to modify my class NomClient, i understood that my NomCli class was the problen and not the use of vector, so here is a new step but no solution yet , so here is my Modified NomClient Class :
public class NomClient implements Comparable<NomClient> {
String nom;
public String getNom() {
return this.nom;
}
public void setNom(final String nom) {
this.nom = nom;
}
#Override
public String toString() {
return this.nom;
}
#Override
public int compareTo(NomClient other) {
System.out.println("nom : "+this.nom);
System.out.println("nom to string : "+this.nom.toString());
System.out.println(other.nom);
System.out.println("compare to : "+other.nom.toString());
int last = this.nom.toString().compareTo(other.nom.toString());
return last == 0 ? this.nom.compareTo(other.nom) : last;
}
}
i also have added Collection sort just before the return statement in sselect.listenomclientfidelite(),
like this :
Collections.sort(requete);
return requete.toArray(new Object[0]);
Now i have to deal with a java.lang.NullPointerException. "other" is null
Does any one have a clue to properly sort my combobox ?
If you can't change the NomClient class so that it implements Comparable<NomClient>, meaning that you'd have to give it a public int compareTo(NomClient o) method, then use a Comparator<NomClient> in your sort method call. This is a class that you create that has one method, public int compare(NomClient o1, NomClient o2), and that returns a -1, 0, or 1, depending on if o1 is functionally less than, equal to or greater than the o2 parameter. You would pass your Comparator instance as the 2nd paramter in your Collections.sort(myCollection, myComparator) method call.
Note that your problem has nothing to do with use of a Vector, and all to do with the NomClient class not implementing Comparable.
thank to Hovercraft Full Of Eels his solution was the good one.
i realised the first item of my vector was null it's why the comparable methode failed. so i worked around to handle this case, and here are the final implementation :
for NomClient.java :
public class NomClient implements Comparable<NomClient> {
String nom;
public String getNom() {
return this.nom;
}
public void setNom(final String nom) {
this.nom = nom;
}
#Override
public String toString() {
return this.nom;
}
#Override
public int compareTo(NomClient other) {
// compareTo should return < 0 if this is supposed to be
// less than other, > 0 if this is supposed to be greater than
// other and 0 if they are supposed to be equal
int last = 10;
if (other != null){
last = -10;
if (this.nom != null){
last = this.nom.compareTo(other.nom);
}
}
return last;
for Select.listenomclientfidelite()
public static Object[] listenomclientfidelite() {
final Vector<NomClient> requete = new Vector<NomClient>();
try {
c = Connexion.getCon();
final String sql = "SELECT DISTINCT NOMCLIENT FROM CARTE_DE_FIDELITE INNER JOIN CLIENT ON CLIENT.IDCLIENT=CARTE_DE_FIDELITE.IDCLIENT";
preStm = c.prepareStatement(sql);
rs = preStm.executeQuery();
} catch (final Exception e) {
System.out.print("erreur" + e.getMessage());
}
try {
requete.add(null);
NomClient liste;
while (rs.next()) {
liste = new NomClient();
liste.setNom(rs.getString(1));
requete.add(liste);
System.out.println("listenomclientfidelite, liste is : "+liste);
}
rs.close();
preStm.close();
} catch (final Exception e) {
System.out.print("errorlistenom" + e.getMessage());
}
Collections.sort(requete);
return requete.toArray(new Object[0]);
}
nothing else to do than insert the returned ArrayList in a combobox.