comparator of priorityqueue in java [duplicate] - java

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 5 years ago.
Im trying to use the override comparator method of priorityqueue and i want to achieve the following:
i have the current list:
RG3
PR1
PR2
RG4
RG1
RG2
the RG refers to a regular person and the PR refers to a person with priority, the numbers represent the turns.
what i want is to get a First in first out order except when is a priority person wich will go to the top of the queue in his turn. so in the list i want the following result
PR1
PR2
RG1
RG2
RG3
RG4
heres what ive done until now:
Queue<Ficha> cola = new PriorityQueue<>(6, idComparator);
while (!list.isEmpty()) //this list is the unsorted list.
{
aux = list.remove(0);
cola.add(aux); // adds it to the priority queue
}
while(!cola.isEmpty())
{
aux = cola.poll();
System.out.println(aux.getCod_priority()+aux.getTurn()); // this shows me the order of the queue
}
}
public static Comparator<Ficha> idComparator = new Comparator<Ficha>()
{
#Override
public int compare(Ficha f1, Ficha f2) {
return (int) ((f1.getTurn()+prioridad(f1.getCod_priority())) - (f2.getTurn()+prioridad(f2.getCod_priority())));
}
};
private static long prioridad(String cod_priority) // this method i use it to give the cod_priority a int value to compare
{
if(cod_tipo_ficha=="PR")
{
return 10000;
}
else
{
return 1;
}
}
and when i run it i get the following order:
PR1
RG1
RG2
PR2
RG3
RG4
i know my problem is in the comparator method but i dont know how to achieve the queue that i want.
i know theres a lot of question related of how to compare but the only answers i see is when you compare strings. and this one i need to compare the priority string and the int.

Just change cod_tipo_ficha=="PR" to
if("PR".equals(cod_tipo_ficha)) {
...
}
Should work

Related

Java PriorityQueue with Custom Objects not Sorting Correctly [duplicate]

This question already has answers here:
Why does PriorityQueue.toString return the wrong element order? [duplicate]
(4 answers)
Closed 8 months ago.
I don't completely understand how to use a Java PriorityQueue (max Heap) for custom objects.
I'm working on a LeetCode problem where my code must reorder the words in a sentence by word length. My instinct was that I could use a PriorityQueue to do the work of word-ordering for me. To do that, I thought I could track words with a custom object:
public class word implements Comparable<word>{
public String theWord;
public int len, order;
public word(String w, int order) {
this.theWord = w;
this.order = order;
this.len = w.length();
}
#Override
public int compareTo(word o) {
return this.len - o.len; // sorting behavior controlled here, right???
}
public String toString() {
return this.theWord+"("+this.order+") "; // for troubleshooting
}
}
Then:
public String arrangeWords(String sentence) {
PriorityQueue<word> maxHeap = new PriorityQueue<>(Comparator.naturalOrder());
String[] words = sentence.split(" ");
for( int i=0; i<words.length; i++ ) {
maxHeap.offer( new word(words[i], i) );
}
}
The first sentence I'm using to test is "leetcode is cool". (From the LC post.)
The ordering I'm hoping for is: "is cool leetcode" (shortest-to-longest word order)
But when I run the above code and check the PriorityQueue in the debugger, I see:
is(1) leetcode(0) cool(2)
Sooo... what the heck? I don't understand how this is ordered at all. This is not the original order (indicated by parenthesis), not in length order, not even in alphabetical order. I have no idea how the PriorityQueue is deciding how to order the word objects. I thought that the class word's compareTo() method would force the ordering that I want. (I've seen this with other SO posts.) But not so. Does someone see what I'm going wrong? Thank you.
You inserted them in priority queue. But then you need to poll the queue to get the right order of words.
while (!maxHeap.isEmpty()) {
System.out.println(maxHeap.poll());
}
Also please note the order field won't get altered just because you inserted them in priority queue. It just shows the order in which the word appears in original sentence.
Write that loop after your for loop where you inserted. Then execute again. You will see right order.
PriorityQueue( minHeap) maintains that the top element is of the lowest length . The remaining elements will be in random order. Once you poll the top element, then re-ordering happens( upHeapify -technically ) that makes the smallest from the remaining to become the top element. As already pointed out, you need to poll all the objects and make them part of your sentence.
Also, another way to go about the problem was -> you could have simply used the comparator on the array of String.
class Solution {
public static String arrangeWords(String text) {
String str[] = text.split(" ");
Arrays.sort(str, (a, b) -> a.length() - b.length());
String res = "";
for ( int i = 0; i< str.length; i++)
{
if ( i ==0 )
{
res += str[i].substring(0,1).toUpperCase() + str[i].substring(1) + " ";
}
else{
res += str[i].substring(0,1).toLowerCase() + str[i].substring(1) + " ";
}
}
return res.trim();
}
}

Implemented hashCode() but retainAll() still isn't working as expected [duplicate]

This question already has answers here:
Java Hashset.contains() produces mysterious result
(3 answers)
Closed 4 years ago.
I have a doctor object and each object has a unique attribute "docMobile"(primary key). I made two different LinkedHashSets (doctorsByLoc & doctorsByAvail) of doctors. Now when i do a
doctorsByLoc.retainAll(doctorsByAvail)
on the two sets it deletes all the elements even though both have the same doctors.
I have implemented hashCode() Method in my doctor class. I also printed the sets individually to check in the sets have same elements.
public class Doctor{
String docName;
long docMobile;
String docLocation;
int docDays;
#Override
public int hashCode() {
return Long.hashCode(docMobile);
}
}
Then somewhere in a servlet something like this happens
public static void main(String[] args){
Set<Doctor> doctorsByLoc = new LinkedHashSet<>();
Set<Doctor> doctorsByAvail = new LinkedHashSet<>();
doctorsByLoc.add(d1);
doctorsByLoc.add(d2);
doctorsByLoc.add(d3);
doctorsByAvail.add(d1);
doctorsByAvail.add(d2);
doctorsByAvail.add(d3);
System.out.println("Before retain All "+doctorsByLoc.size());
for(Doctor d:doctorsByLoc){
System.out.println(d.getdocName());
}
doctorsByLoc.retainAll(doctorsByAvail);
System.out.println("After retain All"+doctorsByLoc.size());
for(Doctor d:doctorsByLoc){
System.out.println(d.getdocName());
}
}
Actual output:
Before retain All 3
d1's name
d2's name
d3's name
After retain All 0
How can i fix my hashcode method so that the doctors remain.
I have tried printing the hashcode before returning it and I got pairs of similar hashcode as output.
You did not override equals correctly. You should be overriding it as follows:
#Override
public boolean equals (Object other) // Not "Doctor other"
{
// implementation here
}

How can I access a stack or linked list that's inside an ArrayList? [duplicate]

This question already has answers here:
How to fill a List of Lists?
(3 answers)
Working with a List of Lists in Java
(8 answers)
Closed 5 years ago.
So I'm trying to create "piles" of cards in a class called Table using an ArrayList with stacks inside of it that contain the card objects (which are defined in a separate class).
I initialized it like so:
private MyArrayList<MyStack<Card>> piles;
public Table()
{
MyStack<Card> piles = new MyStack<>();
}
My issue is that I can't figure out how to add things to and from the stack inside the ArrayList. Is my initialization of it wrong? If so, how can I fix it?
Note: MyArrayList and MyStack are just slightly different versions of ArrayList and Stack essentially.
The variable names are a little confusing. Consider:
// private MyArrayList<MyStack<Card>> piles;
private final ArrayList<Stack<Card>> allPiles;
public Table() {
// MyStack<Card> piles = new MyStack<>();
allPiles = new ArrayList<>();
}
then you can do something like this:
public void addCardToPile(Card card, int pileIndex) {
while (allPiles.size() < pileIndex) {
allPiles.add(new Stack<Card>());
}
allPiles.get(pileIndex).push(card);
}
public Card getTopCardFromPile(int pileIndex) {
while (allPiles.size() < pileIndex) {
allPiles.add(new Stack<Card>());
}
if (allPiles.get(pileIndex).isEmpty()) {
return null;
}
return allPiles.get(pileIndex).pop();
}
But it's not clear if ArrayList is the most appropriate here. Consider a Map<Integer, Stack<Card>> allPiles, and instead of pileIndex have something like pileNumber. Or Map<String, Stack<Card>> allPileswith pileName.
Iterate through the list here piles, push card in the Stack.
for (MyStack cards: piles) {
cards.push(new Card);
}

Passing strings to an array through a method [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 6 years ago.
Implement a method for adding elements to the class CacheMemory.
The Class cache memory has an array memory whose length is passed through a constructor.Elements can be added to the array only if it has not been added before and if the length of the arrays added is within the boundaries of the array.(within its length).
This is the code I came up with so far:
public class CacheMemory {
private String[] memory;
public CacheMemory(int length) {
this.memory = new String[length];
}
public void addingElementsToCache(String mem) {
for (int i = 0; i < memory.length; i++) {
if (memory[i] != mem) {
memory[i] = mem;
System.out.println(mem);
break;
} else {
System.out.println("Element already exists");
}
}
}
}
If i call this method without break,of course it will print out the string five times,but I don't want the same string to be printed out five times,I want to add five different strings and then,while loop goes through the array,and comes to element that has already been passed,to print out the message.
Actually , you need to use !string.equals("anotherString") instead of !=,since the != only compare the address of the string ,instead of the content of the string,but the method equals does it.
You got some of the logic wrong. You have to wait until you have checked all elements in the cache before you can decide that it doesn't already exist. And also, you should use .equals() for comparing Strings.
public void addingElementsToCache(String mem)
{
// Loop over slots
for (int i = 0; i < memory.length; i++)
{
if (memory[i] == null) {
// You have reached an unused slot, use it!
memory[i] = mem;
System.out.println(mem);
return;
}
else if (mem.equals(memory[i])) {
// You found a duplicate
System.out.println("Element already exists");
return;
}
}
// You have checked all positions without finding an empty slot
System.out.print("The cache was full, unable to add!");
}
If you exercise this code with
public static void main(String[] args)
{
CacheMemory cache = new CacheMemory(10);
asList("foo", "foo", "bar", "boz", "bar")
.forEach(cache::addingElementsToCache);
}
... it will print the following, which is what I think you expect:
foo
Element already exists
bar
boz
Element already exists

Java get next Enum value or start from first [duplicate]

This question already has answers here:
What's the best way to implement `next` and `previous` on an enum type?
(7 answers)
Closed 7 years ago.
I have an enum in Java as following:
public enum Cars
{
Sport,
SUV,
Coupe
}
And I need to get the next value of the enum. So, assuming I have a variable called myCurrentCar:
private Cars myCurrentCar = Cars.Sport;
I need to create a function that when called set the value of myCurrentCar to the next value in the enum. If the enum does not have anymore values, I should set the variable to the first value of the enum.
I started my implementation in this way:
public Cars GetNextCar(Cars e)
{
switch(e)
{
case Sport:
return SUV;
case SUV:
return Coupe;
case Coupe:
return Sport;
default:
throw new IndexOutOfRangeException();
}
}
Which is working but it's an high maitenance function because every time I modify the enum list I have to refactor the function.
Is there a way to split the enum into an array of strings, get the next value and transform the string value into the original enum? So in case I am at the end of the array I simply grab the first index
Yeah sure, it goes like this
public Cars getNextCar(Cars e)
{
int index = e.ordinal();
int nextIndex = index + 1;
Cars[] cars = Cars.values();
nextIndex %= cars.length;
return cars[nextIndex];
}

Categories