choosing vector legacy class over array list - java

In an interview I was being asked by two questions that are..
When does practically we require the use of vector..?
As per my analysis synchronization is the main reason but they were intrested to know that apart from synchronization what are the other practical reasons that we may prefer the use of vector.
Please advise that apart from synchronization what are the other various reason that we will choose vector legacy collection..!

One difference I can think of is Vector supports Enumeration.You can get create Enumeration easily by calling
Enumeration enums = v.elements();
But in case of ArrayList,you need to do like this:
Enumeration enums = Collections.enumeration(arrayList);

Vectors are used in the variable length argument in java.because Vector can automatically expand based on the argument passed to it.
for example
public int sum(int i...)
{
int sum=0;
for(int s:i)
{
sum=sum+s;
}
return sum;
}
in this method I have passed i as an variable length argument no matter how many integer the user will pass to this method ,this method will return the sum based on the user arguments..
so vector provides this facility to the user.
this is where vectors are implemented.Internally the variable length arguments uses Vector to
store the Data.

Related

Assigning lexical order score to strings

In my current project we have a strange kind of sorting system.
As opposed to the usual way of determining the order of elements by comparing them to one another, we first assign a numeric score to each element and then sort by this score. This way we can sort by different criteria by just changing the score assignment part.
What I want is to define a function on strings such that; f(a) < f(b) if a comes before b in lexical order and vice versa.
The strings are unicode and, we should support case insensitivity.
Is this possible?
Don't get me wrong, but this approach doesn't make sense. Because it means that you can not use Java's "default" mechanism to solve your problem; and that would be: you create own custom Comparator.
Meaning: when sorting collections/arrays of objects of some class, the reasonable way to define their ordering is by providing a comparator that can tell you for any two objects of that class how to order them.
Well, given your setup, that probably means: your comparator needs to be able to compute that score from the provided input objects. And then, it can use further information (like string values) to make further decisions.
Thinking about it again: you should really step back here. If you have a huge codebase that is already using this strange system; then well, you need to define a scoring function that reduces your strings to numbers; and make sure that the score value matches that f(a) < f(b) relation you are looking for. But if you are just starting; seriously: consider dropping your idea of using that scoring function. Instead simply use different comparator implementations to achieve sorting based on changing criteria.
What I want is to define a function on strings such that; f(a) < f(b) if a comes before b in lexical order and vice versa. The strings are unicode and, we should support case insensitivity.
Is this possible?
No, it isn't unless your strings are limited in length. Suppose f("a") = 1. Then, obviously, f("aa") >= 2. Continuing this pattern, f("aa...a") >= n for "aa...a" containing n symbols. Since for any such string f("aa...a") < f("b"), f("b") must be bigger than any n.
Note that if you're using BigDecimal as values of your function instead of integer type, there is a way (though with Unicode it may be a bit tricky, basic idea is no normalize string and convert it byte-by-byte into decimal digits).
You need to implement custom Comparator. Something like this -
import java.util.Comparator;
public class myString {
private String s;
private int score;
// getter & setter
// ...
}
public class ScoredStringComparator implements Comparator<myString>
{
#Override
public int compare(myString x, myString y)
{
// Assume neither string is null.
if (x.getScore() < y.getScore())
{
return -1;
}
if (x.getScore() > y.getScore())
{
return 1;
}
return 0;
}
}
And put the strings into s TreeSet.
TreeSet<myString> stringSet = new TreeSet<myString>(new ScoredStringComparator());
Now, when you need to update a string's score, you can do it in logarithmic time complexity.
stringSet.remove(aString);
aString.setScore(newScore);
stringSet.add(aString);

Passing on a Multi-Dimensional Array to another Method in Java

I have numbers[x][y] and int pm2 = 0;. Is there a way to pass on this Mult-Array onto public static boolean checkNumber(int[] list, int num)? <- the parameters has to be used this way.
I invoked checkNumber(numbers[x][y], pm2);
I need to use the checkNumber method to check if a number has already been entered and returns true if the number is present and false if number is absent.
I am allowed to use multiple methods thought so I did have an idea of doing numbers[x][0] , numbers[x][1] etc, etc and invoking them into multiple checkNumber() methods. I was just wondering if there's a shorter way.
You have single dimensional array as parameter.
So you have to pass one at a time probably in loop.
I was just wondering if there's a shorter way.
No there isn't. The Java language doesn't support any kind of array "slicing", and you can't subvert the type system to allow you to refer use an array with a different type to what it really has.
You need to implement your idea of iterating the int[] component array of the int[][], passing each one to checkNumber(int[], int). Something like this:
for (int[] subarray : numbers) {
checkNumbers(subarray, pm2);
}

Itemizing returned int[] into individual integer variables

I have a function that returns two integers as a list. Is it possible in Java to separate these into individual int variables from the function?
int first, int second = returnsIntList();
Or am I restricted to initializing.
int numbers[] = returnsIntList();
int firstInt = numbers[0];
int secondInt = numbers [1];
I'm trying to increase readability in my program since the two integers can't be described with a single word but I'm unsure if the syntax exists after searching because 90% of the battle with searching these days is knowing the correct terms to search.
No, there's nothing like this in Java.
If there will always be two values with specific meaning, it would be better if they were returned in a custom type with appropriate properties. But otherwise, you just have to make do with storing the array reference in one variable, and then fetching the individual values in separate statements.
You cannot do what you are trying to do.
One of the common practice in Java is use of Value Objects.
To know what Value Objects is have a look here.
You can have a class with getter and setter of the 2 numbers(integers). In the method returnsIntList() you can create an object of the class and set the 2 numbers using the respective set method. The method should then return the object.
You can then get the values from the object from the respective get method.
You can't do this in Java. In this instance you will be limited to initializing. You may want to look into custom data types, then you can just call the numbers through getters.

How to get a sub array of array in Java, without copying data?

I have some library of classes, working with my data, which is being read into buffer. Is it possible somehow to avoid copying arrays again and again, passing parts of data deeper and deeper into processing methods? Well, it sounds strange, but in my particular case, there's a special writer, which divides data into blocks and writes them individually into different locations, so it just performs System.arraycopy, gets what it needs and calls underlying writer, with that new sub array. And this happens many times. What is the best approach to refactor such code?
Arrays.asList(array).subList(x, y).
This method doesn't give you an array, but a List, which is far more flexible.
Many classes in Java accept a subset of an arrays as parameter. E.g. Writer.write(char cbuf[], int off, int len). Maybe this already suffices for your usecase.
There is no real way to wrap any data without copying and receive real array in Java. You just cannot create new array over existing memory. You have basically 2 options:
Use methods that can accept range of array. This was already recommended.
Use wrapper that gives some kind of abstraction that is close to array and is suitable for many applications. Will be described below.
You may use java.nio.Buffer classes hierarchy, especially java.nio.ByteBuffer which offers buffer abstraction on whole array or sub-ranges. Often it is what people need. This also offers many interesting abilities like 'zero copy' flip and flexible byte area representation.
Here is example of wrapping using java.nio.ByteBuffer.
This should be very close to what you need. At least for some operations.
byte [] a1 = {0, 0, 1, 0};
ByteBuffer buf = ByteBuffer.wrap(a1,1,2);
Then you can do on buf any ByteBuffer operation.
Just a warning, buf.array() returns original a1 array (backend) with all elements.
There is no way to declare a subarray in Java if you use built in arrays like byte[]. The reason is: The length of the array is stored with the data, not with the declaration of the reference to it. Hence a subarray which does not copy the data has no place where it can store the length!
So for basic types you can use the mentioned efficient byte array copies and for higher types (List) there are methods available.
You could take the same approach as the String class takes; create a class for immutable objects which are constructed from an array, a start offset and an end offset which offers access to the sub-array. The user of such an object does not have to know the distinction between the whole array or a sub-array. The constructor does not have to copy the array, just store the array reference and its boundaries.
You could use (ArrayList).subList(value1, value2) i belive, perhaps that could help in your case? That is ofcourse if you want to use an ArrayList.
Perhaps instead of working with arrays you should work with a different type that maintains a reference to a slice of the original array, instead of copying the data over, similar to ArraySegment in C#. An additional benefit to this is that you can also shift the slice over the original array on-demand, without creating new instances. Pseudo code:
public class ArraySegment<T> implements Iterable<T>
{
private int from, to;
private T[] original;
public ArraySegment<T>(T[] original, int from, int to)
{
//constructor stuff
}
public T get(int index)
{
return original[index + from];
}
public int size()
{
return to - from + 1;
}
#Override
public Iterator<T> iterator()
{
//Iterator that iterates over the slice
}
//Can support setters on from/to variables
}
Google's Guava libraries support the slice concept in the form of a ByteSource.
Google Guava is a readily available open-source package of functionality, written from the ground up to follow Google best practices, which depend on significant array slicing capabilities.
Have a look on Arrays.copyOfRange(***) methods.

Java: How do I implement a method that takes 2 arrays and returns 2 arrays?

Okay, here is what I want to do:
I want to implement a crossover method for arrays.
It is supposed to take 2 arrays of same size and return two new arrays that are a kind of mix of the two input arrays.
as in [a,a,a,a] [b,b,b,b] ------> [a,a,b,b] [b,b,a,a].
Now I wonder what would be the suggested way to do that in Java, since I cannot return more than one value.
My ideas are:
- returning a Collection(or array) containing both new arrays.
I dont really like that one because it think would result in a harder to understand code.
- avoiding the need to return two results by calling the method for each case but only getting one of the results each time.
I dont like that one either, because there would be no natural order about which solution should be returned. This would need to be specified, though resulting in harder to understand code.
Plus, this will work only for this basic case, but I will want to shuffle the array before the crossover and reverse that afterwards. I cannot do the shuffling isolated from the crossover since I wont want to actually do the operation, instead I want to use the information about the permutation while doing the crossover, which will be a more efficient way I think.
My question is not about the algorithm itself, but about the way to put in in a method(concerning input and output) in Java
Following a suggestion from Bruce Eckel's book Thinking in Java, in my Java projects I frequently include some utility classes for wrapping groups of two or three objects. They are trivial and handy, specially for methods that must return several objects. For example:
public class Pair<TA,TB> {
public final TA a;
public final TB b;
/**
* factory method
*/
public static <TA,TB> Pair<TA,TB> createPair(TA a,TB b ){
return new Pair<TA,TB>(a,b);
}
/**
* private constructor - use instead factory method
*/
private Pair(final TA a, final TB b) {
this.a = a;
this.b = b;
}
public String toString() {
return "(" + a + ", " + b + ")";
}
}
Read the last section of this article:
http://www.yoda.arachsys.com/java/passing.html
To quote:
This is the real reason why pass by
reference is used in many cases - it
allows a method to effectively have
many return values. Java doesn't allow
multiple "real" return values, and it
doesn't allow pass by reference
semantics which would be used in other
single-return-value languages.
However, here are some techniques to
work around this:
If any of your return values are status codes that indicate success or
failure of the method, eliminate them
immediately. Replace them with
exception handling that throws an
exception if the method does not
complete successfully. The exception
is a more standard way of handling
error conditions, can be more
expressive, and eliminates one of your
return values.
Find related groups of return values, and encapsulate them into
objects that contain each piece of
information as fields. The classes for
these objects can be expanded to
encapsulate their behavior later, to
further improve the design of the
code. Each set of related return
values that you encapsulate into an
object removes return values from the
method by increasing the level of
abstraction of the method's interface.
For instance, instead of passing
co-ordinates X and Y by reference to
allow them to be returned, create a
mutable Point class, pass an object
reference by value, and update the
object's values within the method.
As a bonus, this section was updated by Jon Skeet :)
If it is reasonable for the caller to know the size of the returned arrays ahead of time, you could pass them into the method:
public void foo(Object[] inOne, Object[] inTwo, Object[] outOne, Object[] outTwo) {
//etc.
}
That being said, 90+% of the time multiple return values out of a method are hiding a better design. My solution would be to make the transformation inside an object:
public class ArrayMixer {
private Object[] one;
private Object[] two;
public ArrayMixer(Object[] first, Object[] second) {
//Mix the arrays in the constructor and assign to one and two.
}
public Object[] getOne() { return one; }
public Object[] getTwo() { return two; }
}
I suspect that in your real use case that class and array one and array two can get better names.
Since the specification of your method is that it takes two input arrays and produces output arrays, I agree with you that the method should return both arrays at the same time.
I think that the most natural choice of return value is an int[][] of length 2 (substitute int with whatever type you are using). I don't see any reason it should make the code harder to understand, especially if you specify what the contents of the return value will be.
Edit: in response to your comment, I understand that you have considered this and I am saying that despite your stylistic objections, I don't believe there is a strictly "better" alternative ("better" here being loosely defined in the question).
An alternative approach, largely equivalent to this one, would be to define an object that wraps the two arrays. This has the small distinction of being able to refer to them by names rather than array indices.
The best way to do it would be to do
public void doStuff(int[] array1, int[] array2) {
// Put code here
}
Since Java arrays in Java pass the reference, any modifications made to the arrays will be made to the array itself. This has several caveats
If you are setting it to null you must use a different way (such as encapsulating it in an object)
If you are initializing the array (in the method), you must use a different way
You would use this in the format:
// other method
int[] array1 = new int[20]; // the arrays can be whatever size
int[] array2 = new int[20];
doStuff(array1,array2);
// do whatever you need to with the arrays
Edit: This makes the assumption that it is okay to make changes to the input arrays.
If it isn't, then an object (such as in leonbloy's answer is definitely what is called for).
You strictly cannot return more then one value (think object or primitive) in Java. Maybe you could return an instance of a specific "Result" object which has the two arrays as properties?
You could pass the output arrays as parameters to the method. This may give you more control over memory allocation for the arrays too.
The cleanest and easiest to understand way would be to create a container bean that contains two arrays, and return the container from the method. I'd probably also pass in the container into the method, to keep it symmetric.
The most memory efficient way, assuming both arrays are the same length, would be to pass a multidimensional array - Object[2][n] - where n is the length of the arrays.
If you're really against the arbitrary ordering that comes from a 2d array or a collection, perhaps consider making an inner class that reflects the logic of what you're doing. You could simply define a class that holds two arrays and you could have your method return that, with names and function that reflect the logic of exactly what you're doing.
A simple solution to the above problem is to return as Map.The trick of this question is how you will define the keys to identify the objects, let say there are two
input arrays [a,a,a,a] [b,b,b,b] and two outputs arrays [a,a,b,b] [b,b,a,a]
For that you can use String variable as a key just to identify objects because String variable is immutable, so they can be used as keys.
And as example
Map<String,String[]> method(String[] x,String[] y){
do your stuff..........
Hashmap<String,String[]> map =new HashMap<String,String[]>();
map.put("Object2",[b,b,a,a]);
return map;
}

Categories

Resources