Implementing Set <T>T[] toArray(T[] a)

  • (2 Pages)
  • +
  • 1
  • 2

18 Replies - 4061 Views - Last Post: 31 May 2012 - 06:15 PM Rate Topic: -----

#16 cre8tion  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 19
  • Joined: 29-May 12

Re: Implementing Set <T>T[] toArray(T[] a)

Posted 31 May 2012 - 12:24 PM

View Postbaavgai, on 31 May 2012 - 05:59 AM, said:

View PostKakerergodt, on 31 May 2012 - 07:32 AM, said:

probably not the most elegant solution.


The way Java handles generics in respect to arrays ain't all that elegant. Nice work around.

Now I was confused as to why the array was passed at all. A full implementation is a little wonky.
toArray

Quote

<T> T[] toArray(T[] a)

Returns an array containing all of the elements in this set; the runtime type of the returned array is that of the specified array. If the set fits in the specified array, it is returned therein. Otherwise, a new array is allocated with the runtime type of the specified array and the size of this set.

If this set fits in the specified array with room to spare (i.e., the array has more elements than this set), the element in the array immediately following the end of the set is set to null.
-- http://docs.oracle.c...a/util/Set.html


Also, I saw this question before, the implementation of Set and Iterable. So:
public class LinkedSet<T> implements Set<T>, Iterable<T> {
	@Override
	public <T2> T2[] toArray(T2[] ts) {
		int size = this.size();
		if (ts.length>size) { ts = Arrays.copyOf(ts, size); }
		int i = 0;
		// if we implement Iterable, use it.
		for(T item : this) { ts[i++] = (T2)item; }
		if (size<ts.length) { ts[size] = null; }
		return ts;
	}




Which is why I mentioned the T2 thing, but I buggered it in the first post. :P Still, I think it's a good idea to avoid type confusion.


Thank you for clarifying. However, if you pass the method an empty array, ts.length is never going to be > size. Did you mean < ?
Was This Post Helpful? 0
  • +
  • -

#17 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon


Reputation: 6996
  • View blog
  • Posts: 14,635
  • Joined: 16-October 07

Re: Implementing Set <T>T[] toArray(T[] a)

Posted 31 May 2012 - 01:12 PM

View Postcre8tion, on 31 May 2012 - 03:24 PM, said:

However, if you pass the method an empty array, ts.length is never going to be > size.


Why?

The empty array can be larger. That's the point of taking on the null. e.g.
String buff = new String[100];
LinkedSet<String> ls = LinkedSet<String>();
ls.add("Alpha");
ls.add("Bravo");
buff = ls.toArray(buff);
// do something ...
ls.add("Charlie");
ls.add("Delta");
buff = ls.toArray(buff);
// do something ...



I'm not saying I entirely agree with the logic, but that's how they wrote the spec. :P
Was This Post Helpful? 1
  • +
  • -

#18 cre8tion  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 19
  • Joined: 29-May 12

Re: Implementing Set <T>T[] toArray(T[] a)

Posted 31 May 2012 - 01:47 PM

View Postbaavgai, on 31 May 2012 - 01:12 PM, said:

View Postcre8tion, on 31 May 2012 - 03:24 PM, said:

However, if you pass the method an empty array, ts.length is never going to be > size.


Why?

The empty array can be larger. That's the point of taking on the null. e.g.
LinkedSet<String> ls = LinkedSet<String>();
ls.add("Alpha");
ls.add("Bravo");
ls.add("Charlie");
ls.add("Delta");
buff = ls.toArray(buff);
// do something ...



I'm not saying I entirely agree with the logic, but that's how they wrote the spec. :P


The new array can be larger, but it can be the same size. The method ALWAYS returns an array, either the same size as the set or a bigger size as you indicated. Lets say I just want to convert it to a String array.

LinkedSet<String> ls = LinkedSet<String>();
ls.add("Alpha");
ls.add("Bravo");
ls.add("Charlie");
ls.add("Delta");
Object array[] = ls.toArray(new String[0]);



This will not work with your if statement because array.length (0) is < size(of set = 4). It should return an array modified to fit the set.

Is the if statement really necessary?
if (ts.length < size) {


Was This Post Helpful? 0
  • +
  • -

#19 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon


Reputation: 6996
  • View blog
  • Posts: 14,635
  • Joined: 16-October 07

Re: Implementing Set <T>T[] toArray(T[] a)

Posted 31 May 2012 - 06:15 PM

Oops, you are correct, it should have been the other direction

Updated code:
public <T2> T2[] toArray(T2[] ts) {
	int size = this.size();
	if (ts.length < size) { ts = Arrays.copyOf(ts, size); }
	int i = 0;
	for(T item : this) { ts[i++] = (T2)item; }
	if (size<ts.length) { ts[size] = null; }
	return ts;
}



View Postcre8tion, on 31 May 2012 - 04:47 PM, said:

Is the if statement really necessary?
if (ts.length < size) {



I believe so. According to how the method is supposed to behave in the interface specification.

Here's some test code:
void print(String name, String [] list) {
	System.out.println(name + " capacity = " + list.length);
	int i = 0;
	for(; i < list.length; i++ ) {
		if (list[i]==null) { break; }
		System.out.println((i + 1) + " " + list[i]);
	}
	System.out.println(i + " items");
	System.out.println();
	
}

void test() {
	String [] buff = new String[3];
	LinkedSet<String> ls = new LinkedSet<String>();
	ls.add("Alpha");
	ls.add("Bravo");
	print("buff", buff);

	System.out.println("call toArray");
	String [] buff2 = ls.toArray(buff);
	print("buff", buff);
	print("buff2", buff2);

	ls.add("Charlie");
	ls.add("Delta");
	System.out.println("call toArray");
	String [] buff3 = ls.toArray(buff);
	print("buff", buff);
	print("buff2", buff2);
	print("buff3", buff3);
}



Results:
buff capacity = 3
0 items

call toArray
buff capacity = 3
1 Bravo
2 Alpha
2 items

buff2 capacity = 3
1 Bravo
2 Alpha
2 items

call toArray
buff capacity = 3
1 Bravo
2 Alpha
2 items

buff2 capacity = 3
1 Bravo
2 Alpha
2 items

buff3 capacity = 4
1 Delta
2 Charlie
3 Bravo
4 Alpha
4 items



If it will fit, it should be the same instance of the array. If not, then it makes a new one.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2