Loop through a LinkedList - java

I'm trying to get a LinkedList from my buffer class (BufferCharacter) and then loop through every element in the LinkedList in the Reader class. But when I try return the LinkedList in the get() method in BufferCharacter class I then cannot loop through it in the Reader class. I've tried to loop through the List in the Buffer class and then return each element from there but that doesn't work either.
Any help is highly appreciated!
public class CharacterBuffer {
private char ch;
private LinkedList buffer = new LinkedList();
private boolean filled;
public void put(char ch) {
buffer.addLast(ch);
}
public void filled() {
filled = true;
}
public Object get() throws InterruptedException {
while (buffer.isEmpty()) {
// wait();
return "Waiting";
}
return buffer;
}
public synchronized void putSync(char ch) {
buffer.addLast(ch);
}
public synchronized Object getSync() throws InterruptedException {
while (buffer.isEmpty()) {
// wait();
return "---------";
}
for(int i = 0; i<buffer.size(); i++){
System.out.println(buffer.get(i));
}
return buffer;
}
public int size(){
return buffer.size();
}
}
public class Reader extends Thread {
private GUIMutex gui;
private CharacterBuffer buffer;
private boolean isSynced;
public Reader(GUIMutex gui, CharacterBuffer buffer, boolean isSynced) {
this.gui = gui;
this.buffer = buffer;
this.isSynced = isSynced;
}
public void run() {
String data = "test";
while (true) {
try {
// data = buffer.get();
if (isSynced) {
gui.setReaderText(buffer.getSync() + "\n");
} else {
for(int i = 0; i<buffer.get().size(); i++){
gui.setReaderText(i);
}
gui.setReaderText(buffer.get() + "\n");
}
Thread.sleep(700);
} catch (InterruptedException e) {
}
}
}
}

I think you don't understand what you are talking about; so lets try to shed some light here.
In the end, you are talking about some kind of "collection" class that contains multiple elements; in your case a LinkedList. The thing is: in order to make use of such a class, you need a clear understanding of the APIs you intend to provide.
You figured that you want to use that buffer to store individual char values, that you add using putSync().
But then ... what exactly is getSync() supposed to do?
In your case, you are simply returning the buffer, and that is probably wrong.
Instead, you want to have methods like:
synchronized boolean hasNext()
and
synchronized char getNext()
A user of your class can call the first method to figure: are there other chars; and if so, the second method returns those values.
That would a first, simple way to improve your code. A more reasonable way would be that you implement a method getIterator() that would return an object implementing the Iterator interface.
Other things to note: if you are using the "built-in" LinkedList; please understand that this class supports generics!
Thus you should be using it like:
private final List<Character> buffer = new LinkedList<>();
to get all the benefits from using strongly typed collections!
EDIT: upon your comments, I think using a LinkedList is simply the wrong approach here.
Instead of using a List, you want to use a Queue, like:
private final Queue<Character> buffer = new ConcurrentLinkedQueue<>();
That class gives you that functionality that one party can add elements at the queue tail; whereas another party removes elements from the queue head.
Extra bonus: that class is doing the synchronisation work for you already, so you don't need to care about that!

Use StringBuilder instead
StringBuilder sb = new StringBuilder(128);
// add chars using sb.append(char)
for (int i = 0, n = sb.length(); i < n; i++)
{
char c = sb.charAt(i);
}
or
String s = sb.toString();

Related

Java Queues and Stacks

I have a small problem that I'm hoping someone could help me with.
This is an assignment, so I am not supposed to use classes imported from the java API nor am I supposed to do this in any other way (arraylist would have made this much easier.)
I created a Queue class and a Stack class.
I am trying to retrieve the head of the Queue, and add it to the Stack.
I am guessing I will need to create a method that somehow gets the value of the head of the list and stores it so I can use it.
For example, if I enqueued " bob", "jack", and "jill" to the Queue in that order, it will look like:
bob
jack
jill
I want to dequeue bob from the queue list, but add him to the head of the Stack list, but I can't figure out how. I'm sorry if my question is not very precise, I'm having problems wording what I really need. If any other information is needed I will update my post. Thanks for any help.
Here is my Queueclass:
(LL is my Link List class)
public class Queue<T extends Comparable<T>> {
LL<T> theQueue;
public Queue() {
theQueue = new LL<T>();
}
public boolean isEmpty() {
return theQueue.isEmpty();
}
public void enqueue(T value) {
theQueue.insertTail(value);
}
public T dequeue() throws QueueException {
T retval = null;
try {
retval=theQueue.deleteHead();
}catch (LLException e) {
throw new QueueException ("Queue is empty");
}
return retval;}
public String toString() {
return theQueue.toString();
}}
And my Stack Class:
public class Stack<T extends Comparable<T>>{
LL<T> theStack;
public Stack()
{
theStack = new LL<T>();
}
public boolean isEmpty()
{
return theStack.isEmpty();
}
public void push(T value)
{
theStack.insertHead(value);
}
public T pop() throws StackException
{
T retval = null;
try
{
retval = theStack.deleteHead();
}
catch (LLException e)
{
throw new StackException("Stack Underflow");
}
return retval;
}
public boolean isFull()
{
return false;
}
public String toStrin()
{
return theStack.toString();
}
Main Class:
public static void main(String[] args) {
Stack <String> hired = new Stack<String>();
Stack <String> fired = new Stack<String>();
Queue <String> apps = new Queue<String>();
String temp;
for (int i = 0; i < 1000; i++) {
System.out.println("Enter the number of the action to perform:");
System.out.println("1. Accept Application");
System.out.println("2. Hire");
System.out.println("3. Fire");
System.out.println("4. Exit");
Scanner kb = new Scanner(System.in);
int key = kb.nextInt();
switch (key) {
case 1:
System.out.println("Enter applicant's name and ID separated by semi-colon:");
String applicant = kb.next() + "\n";
System.out.println("You entered " + applicant);
apps.enqueue(applicant);
break;
case 2:
try{
temp = apps.dequeue();
} catch (QueueException s) {
}
try{ apps.dequeue(); }
catch (QueueException s){
System.out.println("Queue is empty");}
hired.push(temp);
case 3:
System.out.println();
case 4: System.out.println("Bye");
System.exit(0);
}
}
So it won't let me assign apps.dequeue() to temp without the try and catch. but then when I do hired.push(temp); I get an error saying temp may have not been initialized.
I think what you want to do is "To dequeue "bob" from the Queue and add it to the Stack", isn't it?
So I think you have already tell what to do:
Queue<String> q = new Queue<String>();
Stack<String> s = new Stack<String>();
// ... enqueue three strings
String temp = q.dequeue();
s.push(temp);
Yes - this task has nothing to do with the implementation of your Queue and Stack class. It's only about using the interface. As long as you have implemented them correctly, these code work.
EDIT
So maybe this is what you want:
String temp = ""; // explicitly initialize
try {
temp = q.dequeue();
s.push(temp);
} catch {
}
I put both dequeue and push in try block: if dequeue fails, nothing is to be pushed. Is this right for you ?
Use iterator (if you need to push value from a random position of queue into stack). For your assignment, simply dequeue method should work fine as pointed in another answer.
Before calling the dequeue method, call this iterator and check if hasNext(). if true, get the value using iterator.next() and store it.
Now you have the value in 'head' position. Now call dequeue method and delete the head value. Now simply push your stored value into stack

Populating a Boolean Array in Java

As a fairly green Java coder I've set myself the hefty challenge of trying to write a simple text adventure. Unsurprisingly, I've encountered difficulties already!
I'm trying to give my Location class a property to store which exits it contains. I've used a boolean array for this, to essentially hold true/false values representing each exit. I'm not entirely convinced that
a) this is the most efficient way to do this and
b) that I'm using the right code to populate the array.
I would appreciate any and all feedback, even if it is for a complete code over-haul!
At present, when instantiating a Location I generate a String which I send through to the setExits method:
String e = "N S U";
secretRoom.setExits(e);
In the Location class, setExits looks like this:
public void setExits(String e) {
if (e.contains("N"))
bexits[0] = true;
else if (e.contains("W"))
bexits[1] = true;
else if (e.contains("S"))
bexits[2] = true;
else if (e.contains("E"))
bexits[3] = true;
else if (e.contains("U"))
bexits[4] = true;
else if (e.contains("D"))
bexits[5] = true;
}
I'll be honest, I think this looks particularly clunky, but I couldn't think of another way to do it. I'm also not entirely sure now how to write the getExits method...
Any help would be welcome!
The most efficient and expressive way is the following:
Use enums as Exits and use an EnumSet to store them. EnumSet is an efficient Set implementation that uses a bit field to represent the enum constants.
Here is how you can do it:
public enum Exit { North, West, South, East, Up, Down; }
EnumSet<Exit> set = EnumSet.noneOf(Exit.class); // An empty set.
// Now you can simply add or remove exits, everything will be stored compactly
set.add(Exit.North); // Add exit
set.contains(Exit.West); // Test if an exit is present
set.remove(Exit.South); //Remove an exit
Enum set will store all exits in a single long internally, so your code is expressive, fast, and saves a lot of memory.
Is there any reason why you are doing this with Strings and aren't passing in booleans, i.e.
public void setExits(boolean N, boolean E, boolean S, boolean W, boolean U, boolean D)
Or having setters?
public void setNorthOpen(boolean open)
{
bexits[4] = open;
}
Secondly, why are you storing the exits as an array of booleans, it's a small finite set, why not just
boolean N,S,E,W,U,D;
As then you don't need to keep track of which number in the array each direction is.
Also
This is a correct answer (if not completely optimal like that of #gexicide) but I fully encourage anyone to look at the other answers here for an interesting look at how things can be done in Java in different ways.
For future reference
Code which works belongs on Code Review, not Stack Overflow. Although as #kajacx pointed out, this code shouldn't -in fact- work.
OK, first of all, your setExits() method will not work as intended, chained if-elseif will maximally execute 1 branch of code, for example:
if (e.contains("N"))
bexits[0] = true;
else if (e.contains("W"))
bexits[1] = true;
Even if e contains both N and W, only bexits[0] will be set. Also this method will only add exits (for example calling setExits("") will not delete any existing exits.
I would change that method to:
bexits[0] = e.contains("N");
bexits[1] = e.contains("W");
...
Also, i definetly wouldn't remember that north is on index 0, west in on 1, ... so a common practice is to name your indexes using final static constants:
public static final int NORTH = 0;
public static final int WEST = 1;
...
Then you can write in your setExits method:
bexits[NORTH] = e.contains("N");
bexits[WEST] = e.contains("W");
...
(much more readible)
Finally, if you want your code even more well-arranged, you can make a Exits class representing avaliable exits, and backed by boolean array. Then on place where you create your String, you could create this class instead and save yourself work with generating and then parsing a string.
EDIT:
as #gexicide answers, there is a really handy class EnumSet which would be probably better for representing the exits than bollean array.
The EnumSet in the other answer is the best way to do this, I just wanted to add one more thing though for the future when you start looking not just at whether you can move but where you are moving to.
As well as EnumSet you also have EnumMap.
If you define a Room class/interface then inside the Room class you can have
Map<Direction, Room> exits = new EnumMap<>(Direction.class);
You can now add your links into the map as follows:
exits.put(Direction.NORTH, theRoomNorthOfMe);
Then your code to move between rooms can be very general purpose:
Room destination=currentRoom.getExit(directionMoved);
if (destination == null) {
// Cannot move that way
} else {
// Handle move to destination
}
I would create an Exit enum and on the location class just set a list of Exit objects.
so it would be something like:
public enum Exit { N, S, E, W, U, D }
List<Exit> exits = parseExits(String exitString);
location.setExits(exits);
Given what your code looks like, this is the most readable implementation I could come up with:
public class Exits {
private static final char[] DIRECTIONS = "NSEWUD".toCharArray();
public static void main(String... args) {
String input = "N S E";
boolean[] exits = new boolean[DIRECTIONS.length];
for(int i = 0; i< exits.length; i++) {
if (input.indexOf(DIRECTIONS[i]) >= 0) {
exits[i] = true;
}
}
}
}
That being said, there's a number of cleaner solutions possible. Personally I would go with enums and an EnumSet.
By the way, your original code is incorrect, as it will set as most one value in the array to true.
If you're defining exits as a string, you should use it. I would do it like:
public class LocationWithExits {
public static final String NORTH_EXIT="[N]";
public static final String SOUTH_EXIT="[S]";
public static final String EAST_EXIT="[E]";
public static final String WEST_EXIT="[W]";
private final String exitLocations;
public LocationWithExits(String exitLocations) {
this.exitLocations = exitLocations;
}
public boolean hasNorthExit(){
return exitLocations.contains(NORTH_EXIT);
}
public static void main(String[] args) {
LocationWithExits testLocation=new LocationWithExits(NORTH_EXIT+SOUTH_EXIT);
System.out.println("Has exit on north?: "+testLocation.hasNorthExit());
}
}
using array of booleans might cause a lot of problems if you forget what exactly means bexits[0]. Os it for north or south? etc.
or you can just use enums and list of exits available . Then in methid test if list contain a certain enum value
Personally, I think you can hack it around a bit using an enum and turn the following:
public void setExits(String e) {
if (e.contains("N"))
bexits[0] = true;
else if (e.contains("W"))
bexits[1] = true;
else if (e.contains("S"))
bexits[2] = true;
else if (e.contains("E"))
bexits[3] = true;
else if (e.contains("U"))
bexits[4] = true;
else if (e.contains("D"))
bexits[5] = true;
}
into
public enum Directions
{
NORTH("N"),
WEST("W"),
SOUTH("S"),
EAST("E"),
UP("U"),
DOWN("D");
private String identifier;
private Directions(String identifier)
{
this.identifier = identifier;
}
public String getIdentifier()
{
return identifier;
}
}
and then do:
public void setExits(String e)
{
String[] exits = e.split(" ");
for(String exit : exits)
{
for(Directions direction : Directions.values())
{
if(direction.getIdentifier().equals(exit))
{
bexits[direction.ordinal()] = true;
break;
}
}
}
}
Although after having written it down, I can't really tell you if it's that much better. It's easier to add new directions, that's for sure.
All the approaches listed in the answeres are good. But I think the approach you need to take depends on the way you are going to use the exit field. For example if you are going to handle exit as strings then Ross Drews approach would require a lot of if-else conditions and variables.
String exit = "N E";
String[] exits = exit.split(" ");
boolean N = false, E = false, S = false, W = false, U = false, D = false;
for(String e : exits){
if(e.equalsIgnoreCase("N")){
N = true;
} else if(e.equalsIgnoreCase("E")){
E = true;
} else if(e.equalsIgnoreCase("W")){
W= true;
} else if(e.equalsIgnoreCase("U")){
U = true;
} else if(e.equalsIgnoreCase("D")){
D = true;
} else if(e.equalsIgnoreCase("S")){
S = true;
}
}
setExits(N, E, S, W, U, D);
Also if you have an exit and you want to check whether a location has that particular exit then again you will have to do the same
public boolean hasExit(String exit){
if(e.equalsIgnoreCase("N")){
return this.N; // Or the corresponding getter method
} else if(e.equalsIgnoreCase("E")){
return this.E;
} else if(e.equalsIgnoreCase("W")){
return this.W;
} else if(e.equalsIgnoreCase("U")){
return this.U;
} else if(e.equalsIgnoreCase("D")){
return this.D;
} else if(e.equalsIgnoreCase("S")){
return this.S;
}
}
So if you are going to manipulate it as a string, in my opinion the best approach would be to go for list and enum. By this way you could do methods like hasExit, hasAnyExit, hasAllExits, hasNorthExit, hasSouthExit, getAvailableExits etc etc.. very easily. And considering the number of exits (6) using a list (or set) wont be an overhead. For example
Enum
public enum EXIT {
EAST("E"),
WEST("W"),
NORTH("N"),
SOUTH("S"),
UP("U"),
DOWN("D");
private String exitCode;
private EXIT(String exitCode) {
this.exitCode = exitCode;
}
public String getExitCode() {
return exitCode;
}
public static EXIT fromValue(String exitCode) {
for (EXIT exit : values()) {
if (exit.exitCode.equalsIgnoreCase(exitCode)) {
return exit;
}
}
return null;
}
public static EXIT fromValue(char exitCode) {
for (EXIT exit : values()) {
if (exit.exitCode.equalsIgnoreCase(String.valueOf(exitCode))) {
return exit;
}
}
return null;
}
}
Location.java
import java.util.ArrayList;
import java.util.List;
public class Location {
private List<EXIT> exits;
public Location(){
exits = new ArrayList<EXIT>();
}
public void setExits(String exits) {
for(char exitCode : exits.toCharArray()){
EXIT exit = EXIT.fromValue(exitCode);
if(exit != null){
this.exits.add(exit);
}
}
}
public boolean hasExit(String exitCode){
return exits.contains(EXIT.fromValue(exitCode));
}
public boolean hasAnyExit(String exits){
for(char exitCode : exits.toCharArray()){
if(this.exits.contains(EXIT.fromValue(exitCode))){
return true;
}
}
return false;
}
public boolean hasAllExit(String exits){
for(char exitCode : exits.toCharArray()){
EXIT exit = EXIT.fromValue(exitCode);
if(exit != null && !this.exits.contains(exit)){
return false;
}
}
return true;
}
public boolean hasExit(char exitCode){
return exits.contains(EXIT.fromValue(exitCode));
}
public boolean hasNorthExit(){
return exits.contains(EXIT.NORTH);
}
public boolean hasSouthExit(){
return exits.contains(EXIT.SOUTH);
}
public List<EXIT> getExits() {
return exits;
}
public static void main(String args[]) {
String exits = "N E W";
Location location = new Location();
location.setExits(exits);
System.out.println(location.getExits());
System.out.println(location.hasExit('W'));
System.out.println(location.hasAllExit("N W"));
System.out.println(location.hasAnyExit("U D"));
System.out.println(location.hasNorthExit());
}
}
Why not this if you want a shorter code:
String symbols = "NWSEUD";
public void setExits(String e) {
for (int i = 0; i < 6; i++) {
bexits[i] = e.contains(symbols.charAt(i));
}
}
If you want a generic solution you can use a map, which maps from a key (in your case W, S, E.. ) to a corresponding value (in your case a boolean).
When you do a set, you update the value the key is associated with. When you do a get, you can take an argument key and simply retrieve the value of the key. This functionality does already exist in map, called put and get.
I really like the idea of assigning the exits from a String, because it makes for brief and readable code. Once that's done, I don't see why you would want to create a boolean array. If you have a String, just use it, although you might want to add some validation to prevent accidental assignment of strings containing unwanted characters:
private String exits;
public void setExits(String e) {
if (!e.matches("[NSEWUD ]*")) throw new IllegalArgumentException();
exits = e;
}
The only other thing I would add is a method canExit that you can call with a direction parameter; e.g., if (location.canExit('N')) ...:
public boolean canExit(char direction) {
return exits.indexOf(direction) >= 0;
}
I like enums, but using them here seems like over-engineering to me, which will rapidly become annoying.
**Edit**: Actually, don't do this. It answers the wrong question, and it does something which doesn't need to be done. I just noticed #TimB's answer of using a map (an EnumMap) to associate directions with rooms. It makes sense.
I still feel that if you only need to track exit existence, a String is simple and effective, and anything else is over-complicating it. However, only knowing which exits are available isn't useful. You will want to go through those exits, and unless your game has a very plain layout it won't be doable for the code to infer the correct room for each direction, so you'll need to explicitly associate each direction with another room. So there seems to be no actual use for any method "setExits" which accepts a list of directions (regardless of how it's implemented internally).
public void setExits(String e)
{
String directions="NwSEUD";
for(int i=0;i<directions.length();i++)
{
if(e.contains(""+directions.charAt(i)))
{
bexits[i]=true;
break;
}
}
}
the iterative way of doing the same thing..
Long chains of else if statements should be replaced with switch statements.
Enums are the most expressive way to store such values as long as the efficiency is not a concern. Keep in mind that enum is a class, so creation of a new enum is associated with corresponding overhead.

Why does a concurrent hash map work properly when accessed by two thread, one using the clear() and other using the putifAbsent() methods?

I am implementing an application using concurrent hash maps. It is required that one thread adds data into the CHM, while there is another thread that copies the values currently in the CHM and erases it using the clear() method. When I run it, after the clear() method is executed, the CHM always remains empty, though the other thread continues adding data to CHM.
Could someone tell me why it is so and help me find the solution.
This is the method that adds data to the CHM. This method is called from within a thread.
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentHashMap;
public static ConcurrentMap<String, String> updateJobList = new ConcurrentHashMap<String, String>(8, 0.9f, 6);
public void setUpdateQuery(String ticker, String query)
throws RemoteException {
dataBaseText = "streamming";
int n = 0;
try {
updateJobList.putIfAbsent(ticker, query);
}
catch(Exception e)
{e.printStackTrace();}
........................
}
Another thread calls the track_allocation method every minute.
public void track_allocation()
{
class Track_Thread implements Runnable {
String[] track;
Track_Thread(String[] s)
{
track = s;
}
public void run()
{
}
public void run(String[] s)
{
MonitoringForm.txtInforamtion.append(Thread.currentThread()+"has started runnning");
String query = "";
track = getMaxBenefit(track);
track = quickSort(track, 0, track.length-1);
for(int x=0;x<track.length;x++)
{
query = track[x].split(",")[0];
try
{
DatabaseConnection.insertQuery(query);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
joblist = updateJobList.values();
MonitoringForm.txtInforamtion.append("\nSize of the joblist is:"+joblist.size());
int n = joblist.size()/6;
String[][] jobs = new String[6][n+6];
MonitoringForm.txtInforamtion.append("number of threads:"+n);
int i = 0;
if(n>0)
{
MonitoringForm.txtInforamtion.append("\nSize of the joblist is:"+joblist.size());
synchronized(this)
{
updateJobList.clear();
}
Thread[] threads = new Thread[6];
Iterator it = joblist.iterator();
int k = 0;
for(int j=0;j<6; j++)
{
for(k = 0; k<n; k++)
{
jobs[j][k] = it.next().toString();
MonitoringForm.txtInforamtion.append("\n\ninserted into queue:\n"+jobs[j][k]+"\n");
}
if(it.hasNext() && j == 5)
{
while(it.hasNext())
{
jobs[j][++k] = it.next().toString();
}
}
threads[j] = new Thread(new Track_Thread(jobs[j]));
threads[j].start();
}
}
}
I can see a glaring mistake. This is the implementation of your Track_Thread classes run method.
public void run()
{
}
So, when you do this:
threads[j] = new Thread(new Track_Thread(jobs[j]));
threads[j].start();
..... the thread starts, and then immediately ends, having done absolutely nothing. Your run(String[]) method is never called!
In addition, your approach of iterating the map and then clearing it while other threads are simultaneously adding is likely to lead to entries occasionally being removed from the map without the iteration actually seeing them.
While I have your attention, you have a lot of style errors in your code:
The indentation is a mess.
You have named your class incorrectly: it is NOT a thread, and that identifier ignores the Java identifier rule.
Your use of white-space in statements is inconsistent.
These things make your code hard to read ... and to be frank, they put me off trying to really understand it.

Behavior of return statement in catch and finally

public class J {
public Integer method(Integer x)
{
Integer val = x;
try
{
return val;
}
finally
{
val = x + x;
}
}
public static void main(String[] args)
{
J littleFuzzy = new J();
System.out.println(littleFuzzy.method(new Integer(10)));
}
}
It will return "10".
Now I just replace Return type Integer to StringBuilder and Output was changed.
public class I {
public StringBuilder method(StringBuilder x)
{
StringBuilder val = x;
try
{
return val;
}
finally
{
val = x.append("aaa");
}
}
public static void main(String[] args)
{
I littleFuzzy = new I();
System.out.println(littleFuzzy.method(new StringBuilder("abc")));
}
}
OutPut is "abcaaa"
So, Anybody can explain me in detail.?
what are the differences.?
Just because integer in immutable so after method returns even if value is changed in method it does not reflect, and does reflect in StringBuilder Object
EDIT:
public class J {
public String method(String x) {
String val = x;
try {
return val;
} finally {
val = x + x;
}
}
public static void main(String[] args) {
J littleFuzzy = new J();
System.out.println(littleFuzzy.method("abc"));
}
}
The principal operations on a StringBuilder are the append and insert methods, which are overloaded so as to accept data of any type. Each effectively converts a given datum to a string and then appends or inserts the characters of that string to the string builder. The append method always adds these characters at the end of the builder; the insert method adds the characters at a specified point.
For example, if z refers to a string builder object whose current contents are "start", then the method call z.append("le") would cause the string builder to contain "startle", whereas z.insert(4, "le") would alter the string builder to contain "starlet".
In general, if sb refers to an instance of a StringBuilder, then sb.append(x) has the same effect as sb.insert(sb.length(), x). Every string builder has a capacity. As long as the length of the character sequence contained in the string builder does not exceed the capacity, it is not necessary to allocate a new internal buffer. If the internal buffer overflows, it is automatically made larger.
Instances of StringBuilder are not safe for use by multiple threads. If such synchronization is required then it is recommended that StringBuffer be used.
In above method, finally block is calling everytime.
When an object is passed, the copy of its reference gets passed and you can change the contents if it is mutable.

Java Convert Object[] Array to Vector

What's the best way to convert an Object array to a Vector?
JDE < 1.5
public Vector getListElements()
{
Vector myVector = this.elements;
return myVector;
}
this.elements is an Object[]
Thanks,
rAyt
I should clarify my question
My target platform is a blackberry.
Collections aren't supported. Array.asList() isn't, either :/
Full Class
package CustomElements;
import net.rim.device.api.ui.component .*;
import net.rim.device.api.collection.util.*;
import net.rim.device.api.util.*;
import java.util.*;
public class ContactsList extends SortedReadableList implements KeywordProvider
{
// Constructor
public ContactsList(Vector contacts)
{
super(new ContactsListComparatorByFirstName());
loadFrom(contacts.elements());
}
// Add Element to ContactsSortedReadableList
void addElement(Object element)
{
doAdd(element);
}
public Vector getListElements()
{
return new Vector(Collection
Vector test = this.getElements();
}
// getKeywords
public String[] getKeywords(Object element)
{
return StringUtilities.stringToWords(((Contact)element).get_contactFirstName());
// return StringUtilities.stringToWords(element.toString());
}
// Comparator sorting Contact objects by name
final static class ContactsListComparatorByFirstName implements Comparator
{
public int compare(Object o1, Object o2)
{
// Sticky Entries Implementation
if(((ContactsListObject)o2).getSticky())
{
return 1;
} else
if (((ContactsListObject)o1).getSticky())
{
return -1;
} else
{
if(((ContactsListObject)o1).get_contactFirstName().compareTo(((ContactsListObject)o2).get_contactFirstName()) <0)
{
return -1;
}
if(((ContactsListObject)o1).get_contactFirstName().compareTo(((ContactsListObject)o2).get_contactFirstName()) >0)
{
return 1;
}
else
{
return 0;
}
}
}
}
}
return new Vector(Arrays.asList(elements));
Now, it may look as if you are copying the data twice, but you aren't. You do get one small temporary object (a List from asList), but this provides a view of the array. Instead of copying it, read and write operations go through to the original array.
It is possible to extends Vector and poke its protected fields. This would give a relatively simple way of having the Vector become a view of the array, as Arrays.asList does. Alternatively, just copying data into the fields. For Java ME, this is about as good as it gets without writing the obvious loop. Untested code:
return new Vector(0) {{
this.elementData = (Object[])elements.clone();
this.elementCount = this.elementData.length;
}};
Of course, you are probably better off with a List than a Vector. 1.4 has completed its End of Service Life period. Even 1.5 has completed most of its EOSL period.
In J2ME, you're stuck iterating over the array and add the elements one by one.
Vector v = new Vector();
for (int i = 0; i < this.elements.length; i++) {
v.add(this.elements[i]);
}
A simplified comparator which does basically the same thing.
final static class ContactsListComparatorByFirstName implements Comparator {
public int compare(Object o1, Object o2) {
// Sticky Entries Implementation
ContactsListObject clo2 = (ContactsListObject) o2;
ContactsListObject clo1 = (ContactsListObject) o1;
if (clo2.getSticky()) return 1;
if (clo1.getSticky()) return -1;
return clo1.get_contactFirstName().compareTo(clo2.get_contactFirstName());
}
}
Using generics and ?: it would be just
static final class ContactsListComparatorByFirstName implements Comparator<ContactsListObject> {
public int compare(ContactsListObject clo1, ContactsListObject clo2) {
return clo2.getSticky() ? 1 : // Sticky Entries Implementation
clo1.getSticky() ? -1 :
clo1.get_contactFirstName().compareTo(clo2.get_contactFirstName());
}
}
But to answer your question... (oh I see Tom has what I would put already)
imho your only viable option is:
public Vector getListElements()
Vector vector = new Vector(this.elements.length);
for (int i = 0; i < this.elements.length; i++) {
vector.add(this.elements[i]);
}
return vector;
}
Copy the array elements to the Vector, or
Use Arrays.asList(...) to return a List, which isn't exactly a Vector, but you should be coding the List interface anyway.
A reasonably concise way to do it is something like:
Object[] xx = { 1, "cat", new Point(100,200) };
Vector vv = new Vector(Arrays.asList(xx));
System.out.println("vv=="+vv.toString());
But y'all knew that already, I guess.

Categories