I need to add an "user" into a linked list, and the linked list is a part of a linked list.
public void shibutz(user a){
this.serverList(this.placeInServerList(a.code)).add(a);
server list is the linked list of linked lists.
these are the classes this line uses:
public int placeInServerList(String code){
if (this.serverList.contains(code)){
return indentifyCode(code);
}
return -42;
}
public int indentifyCode (String code){
int counter=0;
Group i= this.serverList.getFirst();
while (this.serverList!=null){
if (i.getCode()==code){
return counter; }
counter++;
i=this.serverList.get(counter);
return indentifyCode (code);
}
return -42;}
group is a linked list.
now, I need help with the first code part. I don't understand what Eclipse wants from me. none of the solutions it's giving me are relative. thanks!!!
Reading this line :
Group i = this.serverList.getFirst()
I assume that serverList is a LinkedList<Group>.
Hence, this is invalid :
public int placeInServerList(String code){
//code is a String, not a Group
if (this.serverList.contains(code))
As serverList is a LinkedList<Group>, the method that you can call is serverList.contains(Group). The methodserverList.contains(String) does not exist.
Related
the scenario is I have a class as below,
#Data
class Operation
{
private String id;
private String name;
private String description;
}
and an ArrayList which contains lots of Operation instances.
For example, there're five instance in the ArrayList,
{"id":"0001", "name":"up"}
{"id":"0002", "name":"down"}
{"id":"0003", "name":"left"}
{"id":"0004", "name":"left"}
{"id":"0005", "name":"up"}
I want to know how many times the name changed in the ArrayList, in this case, the second name is down, it is different with the first one, the change times is 1, the third name is also different with the sceond name, then the change times is 2, but the fourth name as same as the third one, so the change times is still 2, the fifth is different with the fourth, so the change times of this ArrayList is 3.
Is there a way to calculate it without traverse the ArrayList?
List<Operation> operations = List.of(
new Operation("0001", "up"),
new Operation("0002", "down"),
new Operation("0003", "left"),
new Operation("0004", "left"),
new Operation("0005", "up"));
// Don’t include index 0 since it has no previous name to compare with
long numberOfNameChanges = IntStream.range(1, operations.size())
.filter(i -> ! operations.get(i - 1).getName()
.equals(operations.get(i).getName()))
.count();
System.out.println("Count is " + numberOfNameChanges);
Output is:
Count is 3
And it does traverse the list.
For the sake of a complete example I used List.of() (since Java 9) rather than ArrayList, but the stream operation will work just as well with ArrayList too.
I generally say that stream operations don’t work well when operations on more list elements are involved. This seems to be the exception; I find the stream solution just fine myself. If you prefer, you can code it with a loop instead.
PS I’m not very fond of giving working code away when you haven’t shown that much of an effort on your part. Only I found this was easier to explain with code, so I compromised.
Edit
how about we collect set of the values …
No, that won’t work. I give two examples to show you. The simpler one first, I have just removed the final up from your list so there are only 2 value changes:
List<Operation> operations = List.of(
new Operation("0001", "up"),
new Operation("0002", "down"),
new Operation("0003", "left"),
new Operation("0004", "left"));
Set<String> collect = operations.stream()
.map(operation -> operation.name.toLowerCase())
.collect(Collectors.toSet());
System.out.println(collect);
[left, up, down]
Even when I have removed one value change, there are still 3 elements in the set. You may tihnk that you can just subtract 1. Not so. Look at the next and last example:
List<Operation> operations = List.of(
new Operation("0001", "up"),
new Operation("0003", "left"),
new Operation("0002", "up"),
new Operation("0003", "left"),
new Operation("0004", "left"));
Now there are three value changes but only two elements in the set:
[left, up]
And if you subtracted 1, you’d end up with 1.
As you may have realized by now, the problem with the Set approach is it doesn’t take into account when the same name appears again later causing a new value change.
Is there a way to calculate it without traverse the ArrayList?
No.
To look at each value in a list, and compare to the adjacent value, requires traversing the list. There is no magic shortcut.
When you use if(setEvent(index,object)) For exmaple you can make from that event like if(object == "meow) return true; return false;
and if is true it will set if not will not.
You can use abstract class for add events(listener)
public abstract class MyList<Object> {
private ArrayList<Object> list = new ArrayList<>();
public void set(int index,Object object){
if(setEvent(index,object)) list.set(index,object);
}
public void add(Object object){
if(addEvent(object)) list.add(object);
}
public void remove(Object object){
if(removeEvent(object)) list.remove(object);
}
public void remove(int index){
if(removeEvent(index)) list.remove(index);
}
public Object get(int index){
if(getEvent(index)) return list.get(index);
return null;
}
public void clear(){
if(clearEvent()) list.clear();
}
//Abstract
public abstract boolean setEvent(int index, Object object);
public abstract boolean addEvent(Object object);
public abstract boolean removeEvent(Object object);
public abstract boolean removeEvent(int index);
public abstract boolean getEvent(int index);
public abstract boolean clearEvent();
}
I used TreeSet for this and it works in a per snapshot style. In other words, sort once displays once.
Now, I want to implement a realtime sorted table.
Whenever there is a value change in any elements, the sorted table will be updated accordingly.
To make the sorting work on a per update style, I tried to remove the element and add it to the TreeSet again.
quotes.remove(quote);
quotes.add(quote);
It doesn't work because I have to implement the sorting logic in compareTo() but it breaks the contract for identifying the object which makes the remove() work. TreeSet never call equals() and hashcode() as described in the Java Doc.
Any idea? Please advise.
code:
import java.util.TreeSet;
public class TreeSetTest {
public static void main(String args[]) {
TreeSetTest test = new TreeSetTest();
test.onQuoteUpdate("appl", 1000d);
test.onQuoteUpdate("msft", 2000d);
test.onQuoteUpdate("face", 3000d);
test.printTopStocks();
test.onQuoteUpdate("msft", 5000d);
test.printTopStocks();
}
private Set<Quote> quotes = new TreeSet<Quote>();
public void onQuoteUpdate(String symbol, double turnover) {
final Quote quote = new Quote(symbol, turnover);
quotes.remove(quote);
quotes.add(quote);
}
public void printTopStocks() {
System.out.println("--Top Stocks By Turnover--");
for (final Quote quote : quotes) {
System.out.println(quote);
}
}
public static class Quote implements Comparable<Quote> {
private String symbol;
private double turnover;
public Quote(String symbol, double turnover) {
this.symbol = symbol;
this.turnover = turnover;
}
#Override
public int compareTo(Quote o) {
return Double.compare(o.turnover, turnover);
// return symbol.compareTo(o.symbol);
}
}
}
Update 1:
As proposed I tried this:
public static void main(String args[]) {
TreeMapTest test = new TreeMapTest();
test.onQuoteUpdate("appl", 1000d);
test.onQuoteUpdate("msft", 2000d);
test.onQuoteUpdate("face", 3000d);
test.printTopStocks();
test.onQuoteUpdate("face", 50d);
test.printTopStocks();
}
public int compareTo(Quote o) {
if(o.symbol.equals(symbol)) return 0;
return Double.compare(o.turnover, turnover);
}
The remove() return false which eventually there are four elements (expected 3) in the Set.
--Top Stocks By Turnover--
Quote [symbol=face, turnover=3000.0]
Quote [symbol=msft, turnover=2000.0]
Quote [symbol=appl, turnover=1000.0]
remove symbol face : false
add symbol face : true
--Top Stocks By Turnover--
Quote [symbol=face, turnover=3000.0]
Quote [symbol=msft, turnover=2000.0]
Quote [symbol=appl, turnover=1000.0]
Quote [symbol=face, turnover=50.0]
Update 2:
I tried PriorityQueue and here is the code:
https://code.sololearn.com/cb38Eo036c8y/#java
It doesn't work because PriorityQueue doesn't store elements in order. The ordering only works when you poll element from the Queue.
Update 3:
Tried user54321's suggestion that by using a custom collection(see below answer). However, it doesn't look good if there are two more elements having the same value of 'turnover'.
My requirement is a very ordinary one. It seems that none of a collection from JDK fits my case.
Update 4:
The solution from user54321 fits for my interim need.
https://code.sololearn.com/c14Ybab7AOFm/#java
Deleted my previously added answer. Looks like a wrong data structure is being used for the scenario.
Here is why.
When an item is being added or removed, TreeSet does a binary search through the available elements using compareTo().
In your case,
After adding first 3 elements, set looks like this.
[{appl, 1000d}, {msft, 2000d}, {face, 3000d}]
Now when you try to remove the element {face, 50d},
It starts searching at {msft, 2000d},
From compareTo() result it determines {face, 50d} should come before {msft, 2000d}.
And continues to search towards start of the elements ( checking with {appl, 1000d} next).
Since the search doesn't find {face, 3000d}, that element remains without being removed.
Next when you add the element {face,50}, similar search happens and since the search does not find {face, 3000},
It adds {face, 50} to the beginning.
Now the set looks like this.
[{face, 50}, {appl, 1000d}, {msft, 2000d}, {face, 3000d}]
Now the problem here is that compareTo() isn't capable of considering both symbol and turnover for a sensible sorting.
TreeSet can be used for getting a sorted collection of unique elements.
If you need to get a sorted collection of different objects with a particular sorting criteria, in this case turnover value, you can use a PriorityQueue
Update: Using a List and a Set in custom data structure
The problem here is that we have to maintain two conditions.
1. Symbol has to be unique
2. Collection should be sorted by turnover value
compareTo() in Quote can check one at a time and not both.
So in this case we may have to go for a custom data structure.
First use only turnover in compareTo();
#Override
public int compareTo(Quote o) {
return Double.compare(o.turnover, turnover);
}
Then implement the custom data structure.
Note that we are using a HashSet to keep track of the symbol alone.
Using a list so that duplicate turnover values can be kept.
static class QuoteCollection {
Set<String> symbols = new HashSet<>();
List<Quote> quotes = new LinkedList<>();
public void onQuoteUpdate(Quote q) {
if (symbols.contains(q.getSymbol())) {
// this requires quotes.equals() to be implemented
quotes.remove(q);
} else {
symbols.add(q.getSymbol());
}
insertToCollection(q);
}
// inserting at correct position to remain sorted
private void insertToCollection(Quote q) {
int index = Collections.binarySearch(quotes, q);
if (index < 0)
index = ~index; // bitwise compliment to find insert position if it is not available in the list
quotes.add(index, q);
}
public List<Quote> getQuotes() {
return quotes;
}
}
Then use it in the main(). Note that printTopStocks() has been changed a little.
public static void main(String args[]) {
Main test = new Main();
QuoteCollection quoteCollection = new QuoteCollection();
quoteCollection.onQuoteUpdate(new Quote("appl", 1000d));
quoteCollection.onQuoteUpdate(new Quote("msft", 2000d));
quoteCollection.onQuoteUpdate(new Quote("face", 3000d));
test.printTopStocks(quoteCollection.getQuotes());
quoteCollection.onQuoteUpdate(new Quote("face", 50d));
test.printTopStocks(quoteCollection.getQuotes());
}
public void printTopStocks(List<Quote> quotes) {
System.out.println("--Top Stocks By Turnover--");
for (final Quote quote : quotes) {
System.out.println(quote);
}
}
This approach does involve data duplication. However a sorted collection can be maintained at linear time complexity(since it uses 'List.remove()')
Couple of points :
Trying to remove elements even when you are adding it first time.
While updating you are trying to remove new element which does not exist in TreeSet. final Quote quote = new Quote(symbol, turnover); here you are building new element which is Quote("face","50d") which does not exist when you are calling quotes.remove(quote);
Below is the one of the way to solve it, I am hard coding oldQuote to keep it short but you can update it:
public void onAdd(String symbol, double turnover) {
final Quote quote = new Quote(symbol, turnover);
quotes.remove(quote);
quotes.add(quote);
}
public void onQuoteUpdate(String symbol, double turnover) {
final Quote newQuote = new Quote(symbol, turnover);
final Quote oldQuote = new Quote("face", 3000d);
quotes.remove(oldQuote);
quotes.add(quote);
}
public static void main(String args[]) {
TreeSetTest test = new TreeSetTest();
test.onAdd("appl", 1000d);
test.onAdd("msft", 2000d);
test.onAdd("face", 3000d);
test.printTopStocks();
test.onQuoteUpdate("face", 50d);
test.printTopStocks();
}
I'm writing a program which adds telephone entries into a staff phone directory, I want to add the elements to the array in alphabetical order (using surnames) rather than adding the elements then calling Arrays.sort every time a new entry is added, as that would be less efficient. Here is some code I have so far, I'm not sure how to compare each element in the array with the following one and so forth.
public class ArrayDirectory implements Directory {
Entry [] directory = new Entry [50];
#Override
public void addEntry(String initials, String surname, int extension) {
//Entries are added here in alphabetical order
}
Here is my Entry class -
public class Entry {
private String initals,surname;
private int extention;
public Entry(String initals, String surname, int extention){
this.initals = initals;
this.surname = surname;
this.extention = extention;
}
public String getInitals(){
return initals;
}
public String getSurname(){
return surname;
}
public int getExtention(){
return extention;
}
}
Any suggestions, do I override compareTo? Thanks
edit - should have noted I have been asked to use an array. Sorry for the confusion.
Edit 2: updated my addEntry method and overriden compareTo in Entry -
public void addEntry(String initials, String surname, int extension) {
for (int i = 0; i < directory.length; i++) {
if (directory[i] != null) {
int y = directory[i].getSurname().compareTo(surname);
if (y == 1) {
int position = i;
break;
}
} else if (directory[i] == null) {
int position = i;
break;
}
}
}
And my compareTo method -
public int compareTo(Entry other) {
return this.surname.compareTo(other.getSurname());
}
I'm not sure how to shift the elements in the array to the right after I have found the correct position? Thank you for all of you help.
If you dont have to use an array then your using the wrong data structure.
No matter what path you need to implement Comparable:
public class Entry implements Comparable<Entry>{
..
#Override
public int compareTo(Entry other) {
// TODO Auto-generated method stub
return this.surname.compareTo(other.getSurname());
}
..
Consider using a SortedSet:
Set<Entry> map = new TreeSet<Entry>();
map.add(new Entry("JEH", "Hamlet", 123));
map.add(new Entry("AAC", "Adams", 123));
map.add(new Entry("FAM", "Monti", 321));
That will print in the desired order. If you must use an Array then you need to sort it upon insert.
You could make Entry comparable and implement the compareTo in it. But you don't really have to in this case because String is already comparable.
Since this is a homework, I think it will be best to just give you some suggestions on how to proceed, instead of handing you the code -
In your method you do not need to sort the array, you just need to insert it at the correct location in the array.
loop through the array starting at the first index
as you pass through each element in the array, you will have to check following two conditions
is the element null
is the surname of current element greater than surname-argument to the method
as soon as you find the element that satisfies any of the above conditions, record the index and break the loop
then, starting at that index shift the rest of elements to the right
and finally create a new instance of Entry for the provided arguments and set it at that index
Note: This doesn't take care of the situation where you are out of the space in the array.
Update:
I think you mixed up my answer and #David Wallace's answer. It wasn't my suggestion to implement compareTo. Also, it's great that you at least gave it a try and came back.
int position = -1; //declare the position outside (if declared inside, it's not visible outside the loop)
for (int i = 0; i < directory.length; i++) {
// position = i; just assign value of i inside the loop
}
//use the position after the loop
int j = position; // start at position
Entry temp = null; // temp will temporarily hold the entry at the next index
while(true) {
temp = directory[j + 1]; // since we need move entry at j to j+1, first we need save the entry at j+1
directory[j + 1] = directory[j]; // entry at j to j+1
if(temp == null) { // if the next entry is null, don't really need to move no more, so break
break;
}
}
// finally place new entry at index position
directory[position] = //the new Entry
Make Entry implement Comparable<Entry> and write the appropriate compareTo method in your Entry class. Then, in your insert method, you want to
Use Arrays.binarySearch to find the right place in the array to insert your the entry.
Use System.arraycopy to shift everything in the array that's after the appropriate location one place to the right.
Set the appropriate entry.
You'll want to check out the Javadoc for Arrays.binarySearch and System.arraycopy.
Firstly, never use arrays unless you absolutely have to. Use Collecctions instead - they are far easier to deal with and have support for lots of operations you commonly want to perform on groups of things.
In your case, a TreeSet would be a good choice. If you want to sort the entries by surname only in this usage (and not generally), you can pass a customer Comparator to the constructor:
Set<Entry> directory = new TreeSet<>(new Comparator<Entry>() {
#Override
public int compare(Entry o1, Entry o2) {
return o1.getSurname().compareTo(o2.getSurname());
}
});
If your always want to sort Entry objects using surname, have your Entry class implement Comparable<Entry> and move the code into the compareTo() method of the Entry class.
I have a node class defined as below, but I keep on getting the error in Eclipse
void is an invalid type for the variable connectNode
Please explain why?
class Node{
char label;
boolean visited = false;
public Node (char l){
this.label=l;
}
public String toString() {
return Character.toString(label);
}
}
I have defined ArrayList as below:
ArrayList<Node> nodes = new ArrayList<Node>();
I'm trying to use the following method to print the values of Start and End index
public void connectNode(Node start,Node end){
int startIndex=nodes.indexOf(start);
int endIndex=nodes.indexOf(end);
System.out.println(startIndex);
System.out.println(endIndex);
}
Your error usually arises when you try to declare a method inside another method.
Recheck your code and file structure.
Is it possible you're doing something like:
nodes.add(connectNode(start, end));
If that's the case then it means you're trying to insert something that is not suitable for this array list. More specifically you try to put void in a list of type Node.
I am trying to write a code that searches a binary tree for an element and then adds starting at that element. So far I can find the correct position and add to that position, but I lose the rest of the binary tree.
public void add(String addroot, String addleft)
if(root!=nodesearch){
if(root.left!=null){
root=root.left;
add(addroot, addleft);
}
if(root.right!=null){
root=root.right;
add(addroot, addleft);
}
}
else
root=insert();
}
insert() adds the elements and it works fine. Thanks for any help.
Ok so this is what I'm thinking now.
private BinaryStringNode local_root = root
public void add()
if(root!=nodesearch){
if(local_root.left!=null){
local_root=local_root.left;
add();
}
if(local_root.right!=null){
local_root=local_root.right;
add();
}
}
else
local_root=insert();
}
Would local_root=insert() use the insert method on root at the position of local_root. Also would local_root=local_root.right move through root?
First Make it three independent functions
void insert(BinaryStringNode root, BinaryStringNode new_node){
}
int add(BinaryStringNode root){
}
BinaryStringNode find(String name){
}
Now fill the code in as best you can.
When you want to get the sum just call add(find(s)); where s is a string