Let's say i have a list/arrayList or an array of ByteBuffers (List<ByteBuffer> or ByteBuffer[])
It is possible from this to directly get the bytes from the above array without iterating through all the items or computing their total size? I am looking for something like this:
ByteBuffer[] bufferList = new ByteBuffer[7]; //this can be any kind of list of ByteBuffers
//add items to the array
ByteBuffer buffer = (ByteBuffer) bufferList; //what i want to achieve
Of course the last line is not correct.
The thing is that i already have in the array all the bytes in order, but I want them not to be in a list anymore, but in a single ByteBuffer. So is there something that makes possible to create a ByteBuffer from a list/array of ByteBuffers?
Thank you!
public ByteBuffer convertToOne(ByteBuffer[] src)
{
int size=0;
for(int i = 0 ; i < src.length ; i++) {
size+=src[i].array().length;
}
ByteBuffer newBuffer = ByteBuffer.allocate(size);
int sizeAt = 0;
for(int i = 0 ; i < src.length ; i++) {
newBuffer.put(src[i].array(), sizeAt);
sizeAt += src[i].array().length;
}
return newBuffer;
}
I believe you're going to have to create a new ByteBuffer and copy each of the buffers in bufferList into the new one. You should put this functionality in a method so as to not repeat the code each time you use it.
Related
I am trying to full one dimensional array in two dimensional array in Java.
I did it using this way, is there another way better than this?
public double[][] getResult(double[] data, int rowSize) {
int columnSize = data.length;
double[][] result = new double[columnSize][rowSize];
for (int i = 0; i < columnSize; i++) {
result[i][0] = data[i];
}
return result;
}
Edit: i am not going to reuse data-Array i want to set the reference of first column in result-array to the data-array .is it possible? if yes, how can i do this ?
I don't know if this makes sense in your application/context, but for performance reasons you should normally have coherent data as close in the memory as possible.
For Arrays (double[row][column]) that means that data which is has the same row value is normally stored very close in the memory. For example when you have an Array like double[][] d = double[10][10] and save two values like d[0][0] = 1.0; d[1][0] = 2.0;, then they are (I think) 40 bytes away from each other.
But when you save them like d[0][0] = 1.0; d[0][1] = 2.0;, they're directly next to each other in the memory and are normally loaded into the super-fast cache at the same time. When you want to use them iteratively, then that is a huge performance gain.
So for your application, a first improvement would be this:
public double[][] getResult(double[] data, int rowSize) {
int columnSize = data.length;
double[][] result = new double[rowSize][columnSize];
for (int i = 0; i < columnSize; i++) {
result[0][i] = data[i];
}
return result;
}
Secondly, you have to consider whether you are going to re-use the data-Array or not. Because if you don't re-use it, you can just set the reference of the first row in your result Array to the data-Array like this:
result[0] = data;
Again, this gives you another huge performance gain.
Why? Well simply because you don't need to use unnecessary much memory by copying all values - and as you might know, memory allocation can be rather slow.
So always re-use memory instead of copying it wildly.
So my full suggestion is to go with this code:
public double[][] getResult(double[] data, int rowSize) {
double[][] result = new double[rowSize][];
result[0] = data;
return result;
}
It is optional whether you set the columnSize or not.
I need to delete elements from the array points. This is how I do this. The problem is that pts.length is always the same, and the removed elements have the value null. Therefore at some moment I receive the error message java.lang.NullPointerException.
for (int i = 0; i < points.length; i++) {
int ind = r.nextInt(pts.length);
TSPPoint pt = points[ind];
pts = removeElements(points,ind);
solPoints[i] = pt;
System.out.println(pts.length);
}
private static TSPPoint[] removeElements(TSPPoint[] input, int ind) {
List<TSPPoint> result = new LinkedList<TSPPoint>();
for(int i=0; i<input.length; i++)
if(i != ind)
result.add(input[i]);
return (TSPPoint[]) result.toArray(input);
}
What your code seems to (be supposed to) do is to remove random elements from the original array of points and append them to the pts array, i.e., create a permutation of points.
If this is the case, I suggest converting your array to a List and using Collections.shuffle.
#nrathaus has found the bug for you. It's simply that you've got your arrays confused (you're passing points into removeElements, but using pts everywhere else).
But if memory churn is being an issue, there's a much more efficient way to implement removeElements, using System.arraycopy rather than a temporary LinkedList.:
private static TSPPoint[] removeElements(TSPPoint[] input, int ind) {
TSPPoint[] rv;
if (ind >= 0 && ind < input.length) {
// New array will be one smaller
rv = new TSPPoint[input.length - 1];
if (rv.length > 0) {
// Copy the bit before the element we delete
if (ind > 0) {
System.arraycopy(input, 0, rv, 0, ind);
}
// Copy the rest
System.arraycopy(input, ind + 1, rv, ind, input.length - ind);
}
}
else {
// No change
rv = input;
}
return rv;
}
Mind you, if you're doing this a lot, creating and releasing all of these arrays may not be ideal. Using a List throughout may be better.
Wow, for deleting every element you recreate the rest of the array in a LinkedList, which you then turn into an array... The performance of this code, both in time and space, is terrible and so is readability, maintainability and testability.
Why not drop using arrays all together?.. convert points into an ArrayList and use remove(index) directly on that list and use an iterator of the llist to remove multiple elements as you iterate through?
I'm sending a byte array through a socket and I'm receiving it through a DataInputStream. I don't know the size of the byte array, and there's no way to check. I've tried doing this:
byte[] content = new byte[ARRAY_SIZE];
int something;
while((something = inFromStream.read()) > 0)
output.write(something);
This however, still means that I need to know the size of the byte array. I don't want to just fill in a gigantic number (since the byte array received from the stream could be 100 or maybe even 5000000000). How do I deal with this (preferably with the standard Java API/libraries)?
You can send the byte[] piece wise to the OutputStream
byte[] buffer = new byte[1024 /* or some other number */];
int numRead;
while((numRead = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, numRead);
}
The way around - just logic without code sample
getSizeOfInput int countTokens (){
readInput tokenizeInput countTokens
return countTokens }
create an array with the size of countTokens
But all in all - look at the link
create an ArrayList of bytes
I'm developing a chat application in java using DatagramSocket and DatagramPacket .
The data packet received is in terms of bytes .
but i dont Know how to chop of unused bytes
Here is the Code:-
String s,pack[];
byte[] data=new byte[100];
data=dp.getData();//dp is instance of DatagramPacket
s=new String(data)
pack=s.split("-");//Username-ConnectionProtocol-IPaddress
In this code last split gets ip addresss along with the unused data in bytes nearly .
so i need a solution to chop off the unused data in bytes .
like 127.0.0.1[][][][][][][][][].....
i tried to chop string Pack using subtstring() but it will vary in length.
so i need some help in this problem.
You do not need to initialize data with new byte[100], because dp.getData() discards the 100 bytes that you allocated.
If the sender writes more data than is necessary, it is impossible to know how many bytes should be chopped off. The sender should either indicate how many bytes he sends, or you should come up with a heuristic that lets you tell useless bytes from useful ones.
For example, if you know that unused bytes are always at the end of the packet, and that they are always set to zero, you could use this piece of code to set up your string:
data=dp.getData();
int pos = data.length-1;
while (pos != 0 && data[pos] == 0) {
pos--;
}
s=new String(data, 0, pos);
Assuming that the unused part of the packet is zeroed, you can use this kind of code:
static String[] parsePacket(byte[] p) {
return new String(p, 0, len(p)).split("-");
}
static int len(byte[] p) {
for (int i = 0; i < p.length; i++) if (p[i] == 0) return i;
return p.length;
}
What's the most efficient way to put as many bytes as possible from a ByteBuffer bbuf_src into another ByteBuffer bbuf_dest (as well as know how many bytes were transferred)? I'm trying bbuf_dest.put(bbuf_src) but it seems to want to throw a BufferOverflowException and I can't get the javadocs from Sun right now (network problems) when I need them. >:( argh.
edit: darnit, #Richard's approach (use put() from the backing array of bbuf_src) won't work if bbuf_src is a ReadOnly buffer, as you can't get access to that array. What can I do in that case???
As you've discovered, getting the backing array doesn't always work (it fails for read only buffers, direct buffers, and memory mapped file buffers). The better alternative is to duplicate your source buffer and set a new limit for the amount of data you want to transfer:
int maxTransfer = Math.min(bbuf_dest.remaining(), bbuf_src.remaining());
// use a duplicated buffer so we don't disrupt the limit of the original buffer
ByteBuffer bbuf_tmp = bbuf_src.duplicate ();
bbuf_tmp.limit (bbuf_tmp.position() + maxTransfer);
bbuf_dest.put (bbuf_tmp);
// now discard the data we've copied from the original source (optional)
bbuf_src.position(bbuf_src.position() + maxTransfer);
OK, I've adapted #Richard's answer:
public static int transferAsMuchAsPossible(
ByteBuffer bbuf_dest, ByteBuffer bbuf_src)
{
int nTransfer = Math.min(bbuf_dest.remaining(), bbuf_src.remaining());
if (nTransfer > 0)
{
bbuf_dest.put(bbuf_src.array(),
bbuf_src.arrayOffset()+bbuf_src.position(),
nTransfer);
bbuf_src.position(bbuf_src.position()+nTransfer);
}
return nTransfer;
}
and a test to make sure it works:
public static boolean transferTest()
{
ByteBuffer bb1 = ByteBuffer.allocate(256);
ByteBuffer bb2 = ByteBuffer.allocate(50);
for (int i = 0; i < 100; ++i)
{
bb1.put((byte)i);
}
bb1.flip();
bb1.position(5);
ByteBuffer bb1a = bb1.slice();
bb1a.position(2);
// bb3 includes the 5-100 range
bb2.put((byte)77);
// something to see this works when bb2 isn't empty
int n = transferAsMuchAsPossible(bb2, bb1a);
boolean itWorked = (n == 49);
if (bb1a.position() != 51)
itWorked = false;
if (bb2.position() != 50)
itWorked = false;
bb2.rewind();
if (bb2.get() != 77)
itWorked = false;
for (int i = 0; i < 49; ++i)
{
if (bb2.get() != i+7)
{
itWorked = false;
break;
}
}
return itWorked;
}
You get the BufferOverflowException because your bbuf_dest is not big enough.
You will need to use bbuf_dest.remaining() to find out the maximum number of bytes you can transfer from bbuf_src:
int maxTransfer = Math.min(bbuf_dest.remaining(), bbuf_src.remaining());
bbuf_dest.put(bbuf_src.array(), 0, maxTransfer);