Comparator doesn't sort correctly - java

I'm trying to sort an ArrayList containing TurnChoices (I will show the code of this class). So I created a class that implements Comparator https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html
compare method is supposed to return -1,0,1 as the first argument is less than, equal to, or greater than the second, right? I am trying to understand why my ArrayList has the lower TurnChoice on the first index. I could replace 1 by -1 and -1 by 1 but this wouldn't respect what the documentation says and I want to understand what is wrong.
TurnChoiceComparater class:
package pkmnVerDemacia.battle.turn;
import java.util.Comparator;
import pkmnVerDemacia.battle.turn.item.UseItemChoice;
import pkmnVerDemacia.battle.turn.swap.SwapChampionChoice;
import pkmnVerDemacia.model.champion.Champion;
import pkmnVerDemacia.model.champion.stat.STAT;
public class TurnChoiceComparater implements Comparator<TurnChoice>
{
#Override
public int compare(TurnChoice tc1, TurnChoice tc2)
{
if (tc1.getPriority() > tc2.getPriority())
return 1;
else if (tc1.getPriority() == tc2.getPriority()) {
return compareChampSpeed(tc1.getChampionUser(), tc2.getChampionUser());
}
else
return this.getRandomSort();
}
private int compareChampSpeed(Champion c1, Champion c2) {
if (c1.getStat(STAT.SPEED) > c2.getStat(STAT.SPEED)) {
return 1;
}
else if (c1.getStat(STAT.SPEED) < c2.getStat(STAT.SPEED)) {
System.out.println(c2.getName()+" is faster than "+c1.getName()+" so I return -1");
System.out.println("first TurnChoice has Champion: "+c1.getName());
System.out.println("second TurnChoice has Champion: "+c2.getName());
return -1;
}
else
return this.getRandomSort();
}
private int getRandomSort() {
double random = Math.random();
if (random > 0.5)
return 1;
else
return -1;
}
}
Here TurnChoice class
package pkmnVerDemacia.battle.turn;
import pkmnVerDemacia.battle.BATTLE_PARTY;
import pkmnVerDemacia.battle.Battle;
import pkmnVerDemacia.battle.event.BattleEvent;
import pkmnVerDemacia.battle.event.BattleEventQueuer;
import pkmnVerDemacia.model.champion.Champion;
public abstract class TurnChoice
{
protected BattleEventQueuer beQueuer;
protected BATTLE_PARTY userParty;
protected int priority;
public TurnChoice(BattleEventQueuer beQueuer, BATTLE_PARTY userParty, int priority) {
this.beQueuer = beQueuer;
this.userParty = userParty;
this.priority = priority;
}
public int getPriority()
{
return this.priority;
}
public BATTLE_PARTY getUserParty() {
return this.userParty;
}
public BattleEventQueuer getBEQueuer() {
return this.beQueuer;
}
public Champion getChampionUser() {
return this.beQueuer.getChampion(this.userParty);
}
public abstract boolean begin();
}
And here is where I test the code:
public static void sortTurnChoices(ArrayList<TurnChoice> choices)
{
Collections.sort(choices, new TurnChoiceComparater());
for (TurnChoice choice : choices)
System.out.println(choice.getChampionUser().getName());
}
Console result here:
As you can see Vi is faster than Braum so why Braum is at the first index of the ArrayList?

Related

update object in hashmap by java 8 lambda

I created an item named player as follows:
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
public class player implements Comparable <player> {
int PlayerId ;
String name ;
double salary;
public player(int PlayerId) {
this.PlayerId = PlayerId;
}
public void setPlayerId(int PlayerId) {
this.PlayerId = PlayerId;
}
public void setName(String name) {
this.name = name;
}
public void setSalary(double salary) {
this.salary = salary;
}
public int getID() {
return PlayerId;
}
public String getName() {
return name;
}
public double getSalary() {
return salary;
}
#Override
public int hashCode() {
int key = 2;
return key=2*key+PlayerId;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final player other = (player) obj;
if (this.PlayerId != other.PlayerId) {
return false;
}
return true;
}
#Override
public String toString(){
return hashCode()+" "+getID() +" "+getName()+" "+getSalary();
}
// generic method StoreplayerDetails
public <T> void StoreplayerDetails( HashMap<Integer,T> inputMap ) {
// save elements into text file
PrintWriter pw = null;
try {
pw = new PrintWriter(new FileOutputStream("OutPut.txt"));
for(T element : inputMap.values())
pw.println(element);
pw.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(MainProgram.class.getName()).log(Level.SEVERE, null, ex);
} finally {
pw.close();
}
}
#Override
public int compareTo(player other) {
if(this.salary>other.salary)
return 1;
else
if(this.salary<other.salary)
return -1;
return 0;
}
public interface Update {
public <T> void updateSalaries( HashMap<Integer,player> inputMap);
}
}
create an interface named update in the player class ,create a generic method named updateSalaries in the interface that takes a HashMap as input and returns a Queue of player objects after updating the salaries of players by adding 500 to each one's salary .
in the mainprogram class implement the method updatesalaries as a lamdba expression .in the mainprogram class,print the elements in the returned queue .
I tried it as follows but it did not work out:
#Override
public <T> void updateSalaries(HashMap<Integer, player> map) {
map.replaceAll((k,player.getSalary()) -> player.getSalary()+500;
System.out.println("new map"+map);
}
This is the full code in the main class
import java.util.HashMap;
import player.player.Update;
public class MainProgram implements Update{
public static void main(String[] args) {
HashMap< Integer,player> Keys = new HashMap<>();
player p1 =new player(1);
p1.setName("Ali");
p1.setSalary(5000);
player p2 =new player(2);
p2.setName("Sayed");
p2.setSalary(7000);
player p3 =new player(3);
p3.setName("soha");
p3.setSalary(3000);
Keys.put(1, p1);
Keys.put(2, p2);
Keys.put(3, p3);
// p1.StoreplayerDetails(Keys);
MainProgram m = new MainProgram();
m.updateSalaries(Keys);
}
#Override
public <T> void updateSalaries(HashMap<Integer, player> map) {
map.replaceAll((k,player.getSalary()) -> player.getSalary()+500;
System.out.println("new map"+map);
}
}
Is there any help in solving this?
In your code snippet you have the following line of code:
map.replaceAll((k,player.getSalary()) -> player.getSalary()+500;
Let's take this apart piece by piece:
map.replaceAll This method lets you replace all the values in a map. I believe you want to manipulate the values that are already there, instead.
(k,player.getSalary()) This is where you name the variables that the lambda will dump values into. You aren't supposed to supply numbers here, you are supposed to be receiving numbers. You likely want (k, p), where k will be set to the key (an Integer) and p will be set to the value (a player).
player.getSalary()+500 This returns an int. The replaceAll method requires that you return the value type, which in this case is player.
You forgot to include a close parenthesis at the end.
I believe you want to use this line of code instead, which mitigates all of the above errors:
map.forEach((k, p) -> p.setSalary(p.getSalary() + 500));

Initialise Power set as anonymous interface

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class PowerSet {
public static final <E> Collection<Set<E>> of(Set<E> s) {
List<E> src = new ArrayList<>(s);
if (src.size() > 30) {
throw new IllegalArgumentException("Set too big " + s);
}
return new AbstractList<Set<E>>() {
#Override
public int size() {
return 1 << src.size(); // 2 to the power srcSize
}
#Override
public boolean contains(Object o) {
return o instanceof Set && src.containsAll((Set) o);
}
#Override
public Set<E> get(int index) {
Set<E> result = new HashSet<>();
for (int i = 0; index != 0; i++, index >>= 1) {
if ((index & 1) == 1) {
result.add(src.get(i));
}
}
return result;
}
};
}
public static void main(String[] args) {
Collection<Set<String>> set = new HashSet<>();
set.add()... }
I have this code I got from Java Effective as how implement
power set but I am confused how to initialise this set and
fill it with values. There is interface with three overridden
methods, concretely contains, get and size. What does of in class
declaration mean?
To initialize PowerSet instance you need to call it's constructor PowerSet(), though it'll be useless since there is no object related underlying logic in it.
"of" is a static method declared in PowerSet, accepting a set with size <= 30 and returning a List of Sets with logic of power set.
It is implemented by extension of AbstractList.
Set<Long> input = new HashSet<Long>();
input.add(1L);
input.add(2L);
List<Set<Long>> example = PowerSet.<Long>of(input);
So, example.get(0) will result with an empty HashSet, example.get(1) == {1}; example.get(2) == {2}, example.get(3) == {1, 2}
You can rewrite it in a more conventional format:
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class PowerSet<E> extends AbstractList<Set<E>> {
private List<E> src;
public PowerSet(Set<E> s){
//copying set contains to a list to access by index
src = new ArrayList<>(s);
}
#Override
public int size() {
return 1 << src.size(); // 2 to the power srcSize
}
#Override
public boolean contains(Object o) {
return o instanceof Set && src.containsAll((Set) o);
}
#Override
public Set<E> get(int index) {
Set<E> result = new HashSet<>();
for (int i = 0; index != 0; i++, index >>= 1) {
if ((index & 1) == 1) {
result.add(src.get(i));
}
}
return result;
}
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add()...
PowerSet<String> = new PowerSet(set);
}

Customizing the DifferenceListener in XMLUnit

I want to modify the DifferenceListener in XMLUnit to ignore the attribute id while comparing XML files. I have tried to do it using the following.
import org.custommonkey.xmlunit.DifferenceListener;
import org.custommonkey.xmlunit.Difference;
import org.custommonkey.xmlunit.DifferenceConstants;
public class ignoreIDs implements DifferenceListener {
private static final int[] IGNORE_VALUES = new int[] {
DifferenceConstants.ATTR_VALUE.getId(),
};
private boolean isIgnoredDifference(Difference diff) {
int DiffId = diff.getId();
for (int value: IGNORE_VALUES) {
if (DiffId == value) return true;
}
return false;
}
public int differenceFound(Difference difference) {
if (isIgnoredDifference(difference)) return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
else return RETURN_ACCEPT_DIFFERENCE;
}
public void skippedComparison() {
}
}
But I am unable to understand how to enter only the id attribute in the IGNORE_VALUES array. Please help me out.

assertArrayEquals not working in Junit [duplicate]

This question already has answers here:
Using assertArrayEquals in unit tests
(4 answers)
Closed 8 years ago.
I am having issues with my assertArrayEquals in java. It is asking me to create a new method but i am using JUnit so I don't really understand how i can fix this issue.
This is my Junit test case
#Test
public void testSortInsert() throws IOException {
Word tester1 [] = input(0,16);
Word tester2 [] = input(1,256);
Word tester3 [] = input(2,256);
Insertion.sortInsert(tester1);
Word insert1 [] = input(0,16);
StopWatch time = new StopWatch();
time.start();
Insertion.sortInsert(insert1);
time.stop();
int insertTime = timer(time);
assertArrayEquals(insert1,tester1);
}
This is my word file which has my Word ADT. It includes a #overide for equals
package sort;
public class Word implements Comparable<Word>{
private String word;
private int score;
public Word(String w, int s)
{
this.word = w;
this.score = s;
}
public Word() {
// TODO Auto-generated constructor stub
}
public int getScore()
{
return this.score;
}
public void setScore(int s)
{
this.score = s;
}
public String getWord()
{
return this.word;
}
public void setWord(Word w)
{
this.word = w.word;
}
#Override
public int compareTo(Word w)
{
if (this.score > w.score){
return 1;
}
if (this.score < w.score){
return -1;
}
return 0;
}
#Override
public boolean equals(Object x)
{
if (this == x) { return true; }
if (x == null) { return false; }
if (getClass() != x.getClass()) { return false; }
Word other = (Word) x;
if (score != other.score) { return false; }
if (word == null)
{
if (other.word != null) { return false; }
else if (!word.equals(other.word)) { return false; }
}
return true;
}
public String toString()
{
//TODO
return "{" + this.word + "," + this.score + "}";
}
}
Import the static methods in the org.junit.Assert class:
import static org.junit.Assert.*;
or use the class name:
Assert.assertArrayEquals(insert1,tester1);
If you're using JUnit 4 (as it looks like you are), you presumably aren't extending an existing test class - so you need to call the static assertArrayEquals with the class name, e.g.
import org.junit.Assert;
...
Assert.assertArrayEquals(...);
Now, that ends up being a bit clunky, so often developers statically import the methods they want, e.g.
import static org.junit.Assert.assertArrayEquals;
...
assertArrayEquals(...);
or just import everthing:
import static org.junit.Assert.*;
...
assertArrayEquals(...);

Is there a standard library/API/tool for implementing basic "rule chains" in Java?

I am writing a servlet that will be conditionally modifying HTTP headers according to some user-definable rules. (Edit: these rules are defined in an XML file that is read at start-up.) For example, add "X-UA-Compatible: IE=edge,chrome=1" to a response header if it does not already exist and if the request specified a "User-Agent" header matching a known pattern. Not having any better ideas, I attempted to make my own POJOs representing these rules. It "works" but I feel like there must be a more standard or more flexible way to do this.
Are there general-purpose libraries or tools (whether built-in or 3rd-party) that would solve this problem? I have heard and read a little about "rules engines" but they seem like much more complex/heavy tools not meant for problems as simple as mine.
To illustrate what I'm trying to do, I've created a simplified program that applies "rules" to numbers based on "conditions" like "is an even number". Here it is, sorry it's a bit lengthy.
Main.java
package my.example;
import java.util.*;
import my.example.conditions.*;
import my.example.rules.*;
public class Main {
public static void main(String args[]) {
// Some sample objects to evaluate
Collection<Integer> numbers = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8);
print(numbers);
// Define rules
Collection<Rule<Integer>> rules = new ArrayList<Rule<Integer>>();
rules.add(createRuleToMultiplyEvenNumbersBy4());
rules.add(createRuleToAdd1ToEveryNumber());
// Process the rules for each sample object
Collection<Integer> newNumbers = new ArrayList<Integer>();
for (Integer number : numbers) {
Integer newNumber = number;
for (Rule<Integer> rule : rules)
newNumber = rule.apply(newNumber);
newNumbers.add(newNumber);
}
print(newNumbers);
}
private static Rule<Integer> createRuleToMultiplyEvenNumbersBy4() {
MultiplyNumberRule rule = new MultiplyNumberRule(true, 4);
rule.addCondition(new NumberIsEvenCondition());
return rule;
}
private static Rule<Integer> createRuleToAdd1ToEveryNumber() {
AddNumberRule rule = new AddNumberRule(true, 1);
rule.addCondition(new ConstantCondition<Integer>(true));
return rule;
}
private static void print(Collection<Integer> numbers) {
System.out.print("Numbers: ");
for (Integer number : numbers) {
System.out.print(number);
System.out.print(" ");
}
System.out.print("\r\n");
}
}
Condition.java
package my.example.conditions;
public interface Condition<T> {
boolean appliesTo(T obj);
}
ConstantCondition.java
package my.example.conditions;
public class ConstantCondition<T> implements Condition<T> {
private boolean constant;
public ConstantCondition(boolean alwaysReturnThisValue) {
constant = alwaysReturnThisValue;
}
#Override
public boolean appliesTo(T target) {
return constant;
}
}
NumberIsEvenCondition.java
package my.example.conditions;
public class NumberIsEvenCondition implements Condition<Integer> {
#Override
public boolean appliesTo(Integer i) {
return (i % 2 == 0);
}
}
Rule.java
package my.example.rules;
public interface Rule<T> {
T apply(T target);
}
AbstractRule.java
package my.example.rules;
import java.util.*;
import my.example.conditions.Condition;
public abstract class AbstractRule<T> implements Rule<T> {
private Collection<Condition<T>> conditions;
private boolean requireAllConditions;
public AbstractRule(boolean requireAllConditions) {
conditions = new ArrayList<Condition<T>>();
this.requireAllConditions = requireAllConditions;
}
public void addCondition(Condition<T> condition) {
conditions.add(condition);
}
#Override
public T apply(T target) {
boolean isApplicable;
if (requireAllConditions)
isApplicable = allConditionsSatisfied(target);
else
isApplicable = atLeastOneConditionSatisfied(target);
if (isApplicable)
target = process(target);
return target;
}
// Check if all conditions are met
protected boolean allConditionsSatisfied(T target) {
for (Condition<T> condition : conditions) {
if (!condition.appliesTo(target))
return false;
}
return true;
}
// Check if any conditions are met
protected boolean atLeastOneConditionSatisfied(T target) {
for (Condition<T> condition : conditions) {
if (condition.appliesTo(target))
return true;
}
return false;
}
abstract T process(T target);
}
AddNumberRule.java
package my.example.rules;
public class AddNumberRule extends AbstractRule<Integer> {
private Integer addend;
public AddNumberRule(boolean requireAllConditions) {
this(requireAllConditions, 0);
}
public AddNumberRule(boolean requireAllConditions, Integer addend) {
super(requireAllConditions);
this.addend = addend;
}
#Override
public Integer process(Integer i) {
return i + addend;
}
}
MultiplyNumberRule.java
package my.example.rules;
public class MultiplyNumberRule extends AbstractRule<Integer> {
private Integer factor;
public MultiplyNumberRule(boolean requireAllConditions) {
this(requireAllConditions, 1);
}
public MultiplyNumberRule(boolean requireAllConditions, Integer factor) {
super(requireAllConditions);
this.factor = factor;
}
#Override
public Integer process(Integer i) {
return i * factor;
}
}
Well, I'd use Commons Chain
A popular technique for organizing the execution of complex processing
flows is the "Chain of Responsibility" pattern, as described (among
many other places) in the classic "Gang of Four" design patterns book.
Although the fundamental API contracts required to implement this
design patten are extremely simple, it is useful to have a base API
that facilitates using the pattern, and (more importantly) encouraging
composition of command implementations from multiple diverse sources.
it's a common Design Pattern, guess that fits your problem
I have modified the original code attempting to use Commons Chain, but it doesn't seem much different. Luiz E., is this roughly what you are suggesting? It seems like commons-chain does not include any notion of "conditions" -- this is left to the user as part of the implementation of Command.
Main.java
package my.example;
import java.util.*;
import org.apache.commons.chain.*;
import org.apache.commons.chain.impl.*;
import my.example.commands.*;
import my.example.conditions.*;
public class Main {
private static final String NUMBERS = "numbers";
public static void main(String args[]) throws Exception {
// Some sample objects to evaluate
Context context = new ContextBase();
setNumbersInContext(context, Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8));
printNumbersFromContext(context);
// Define rules
Chain ruleChain = new ChainBase();
ruleChain.addCommand(new MultiplyNumberCommand(4, new NumberIsEvenCondition()));
ruleChain.addCommand(new AddNumberCommand(1));
// Process the rules
ruleChain.execute(context);
printNumbersFromContext(context);
}
private static void printNumbersFromContext(Context context) {
Collection<Integer> numbers = getNumbersFromContext(context);
System.out.print("Numbers: ");
for (Integer number : numbers) {
System.out.print(number);
System.out.print(" ");
}
System.out.print("\r\n");
}
#SuppressWarnings("unchecked")
public static Collection<Integer> getNumbersFromContext(Context context) {
Object obj = context.get(NUMBERS);
try {
return (Collection<Integer>) obj;
}
catch (ClassCastException e) {
throw new IllegalStateException("Context did not contain the required data. ClassCastException message is: " + e.getMessage());
}
}
#SuppressWarnings("unchecked")
public static void setNumbersInContext(Context context, Collection<Integer> numbers) {
context.put(NUMBERS, numbers);
}
}
AbstractNumberCommand.java
package my.example.commands;
import static my.example.Main.getNumbersFromContext;
import static my.example.Main.setNumbersInContext;
import java.util.ArrayList;
import java.util.Collection;
import my.example.conditions.Condition;
import org.apache.commons.chain.*;
public abstract class AbstractNumberCommand implements Command {
private boolean continueProcessing = true;
protected Condition<Integer> condition;
protected AbstractNumberCommand(Condition<Integer> condition) {
this.condition = condition;
}
public void continueProcessing(boolean continueProcessing) {
this.continueProcessing = continueProcessing;
}
#Override
public boolean execute(Context context) throws Exception {
Collection<Integer> numbers = getNumbersFromContext(context);
Collection<Integer> newNumbers = new ArrayList<Integer>();
for (int number : numbers)
if (condition.appliesTo(number))
newNumbers.add(modifyNumber(number));
else
newNumbers.add(number);
setNumbersInContext(context, newNumbers);
if (continueProcessing)
return CONTINUE_PROCESSING;
else
return PROCESSING_COMPLETE;
}
protected abstract int modifyNumber(int number);
}
AddNumberCommand.java
package my.example.commands;
import my.example.conditions.*;
public class AddNumberCommand extends AbstractNumberCommand {
private int addend;
public AddNumberCommand() {
this(0);
}
public AddNumberCommand(int addend) {
this(addend, new ConstantCondition<Integer>(true));
}
public AddNumberCommand(int addend, Condition<Integer> condition) {
super(condition);
this.addend = addend;
}
#Override
protected int modifyNumber(int number) {
return number + addend;
}
}
Condition.java
package my.example.conditions;
public interface Condition<T> {
boolean appliesTo(T obj);
}
ConstantCondition.java
package my.example.conditions;
public class ConstantCondition<T> implements Condition<T> {
private boolean constant;
public ConstantCondition(boolean alwaysReturnThisValue) {
constant = alwaysReturnThisValue;
}
#Override
public boolean appliesTo(T target) {
return constant;
}
}
NumberIsEvenCondition.java
package my.example.conditions;
public class NumberIsEvenCondition implements Condition<Integer> {
#Override
public boolean appliesTo(Integer i) {
return (i % 2 == 0);
}
}

Categories