Related
It may sound trivial for you but I am having a hard time visualizing the comparator / array.sort. How can we sort a full array using only 2 arguments? How does it work internally?
for example- Input -[5,3,2,6,8,10,1], Output- [1,2,3,5,6,8,10]
Which algo does it use internally? Which 2 objects does it compare at first? (5 compared to 3?) and then what are the next two objects? (5 compared to 2?) or (3 compared to 2)?
public static void main(String[] args) {
Integer[] tring = new Integer[]{5,3,2,6,8,10,1};
lol(tring);
for(int i=0;i<tring.length;i++){
System.out.println(tring[i]);
}
}
public static void lol(Integer[] args) {
Arrays.sort(args,(h1,h2)->h1-h2);
}
You can visualize the process like this.
Integer[] tring = new Integer[] {5, 3, 2, 6, 8, 10, 1};
Comparator<Integer> comparator = (a, b) -> {
System.out.println(Arrays.toString(tring) + " comparing " + a + " and " + b);
return a.compareTo(b);
};
Arrays.sort(tring, comparator);
System.out.println(Arrays.toString(tring));
result:
[5, 3, 2, 6, 8, 10, 1] comparing 3 and 5
[5, 3, 2, 6, 8, 10, 1] comparing 2 and 3
[5, 3, 2, 6, 8, 10, 1] comparing 6 and 2
[2, 3, 5, 6, 8, 10, 1] comparing 6 and 3
[2, 3, 5, 6, 8, 10, 1] comparing 6 and 5
[2, 3, 5, 6, 8, 10, 1] comparing 8 and 5
[2, 3, 5, 6, 8, 10, 1] comparing 8 and 6
[2, 3, 5, 6, 8, 10, 1] comparing 10 and 5
[2, 3, 5, 6, 8, 10, 1] comparing 10 and 8
[2, 3, 5, 6, 8, 10, 1] comparing 1 and 6
[2, 3, 5, 6, 8, 10, 1] comparing 1 and 3
[2, 3, 5, 6, 8, 10, 1] comparing 1 and 2
[1, 2, 3, 5, 6, 8, 10]
The comparator uses a sort called a TimSort
I personally do not feel qualified to explain the timsort algorithm, but I'm sure you can find plenty of explanations on google.
For the second part of your question, the way the comparator uses your two augments is to determine what order any two given values order should be.
So, for example, say if you wanted to sort [6,4] the comparator would use your function a-b and would then plug in the numbers 6 and 4 and get the 2 and because 2 is positive the sort knows that 6 needs to be behind 4. Which would result in [4,6].
I want to make a section of code that takes a list of lists, splits it into sublists of 9 and remove numbers from all the lists in each of the sublists. However, when my code runs it removes numbers from all the lists, not just the section taken from the original list
for (int startingIndex = 0; startingIndex <= 8; startingIndex++) {
int initialIndex = startingIndex * 9;
ArrayList<ArrayList<String>> gridRow = new ArrayList<ArrayList<String>>();
gridRow.addAll((posabilityGrid.subList(initialIndex, initialIndex+9)));
System.out.println("gridrow - " + gridRow);
ArrayList<String> numbers = new ArrayList<String>();
for (ArrayList<String> posability : gridRow) {
if (posability.size() == 1) {
numbers.add(posability.get(0));
}
}
System.out.println("numbers - " + numbers);
for (ArrayList<String> posability : gridRow) {
posability.removeAll(numbers);
}
System.out.println("newgrid - " + gridRow);
edit:
When the starting index first equals 0:
grid row - [[1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [4], [3], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [2], [1, 2, 3, 4, 5, 6, 7, 8, 9], [9]]
numbers - [4, 3, 2, 9]
it then correctly prints out:
newgrid - [[1, 5, 6, 7, 8], [1, 5, 6, 7, 8], [], [], [1, 5, 6, 7, 8], [1, 5, 6, 7, 8], [], [1, 5, 6, 7, 8], []]
However, when starting index equals 1 at the start:
gridrow - [[1, 5, 6, 7, 8], [1, 5, 6, 7, 8], [5], [1, 5, 6, 7, 8], [1, 5, 6, 7, 8], [9], [1, 5, 6, 7, 8], [1, 5, 6, 7, 8], [1]]
instead of the expected
[[1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [5], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1]]
This section of the list has had the previous numbers removed from it for some reason when it should stay the same so the only the new set of numbers are subtracted
2nd edit:
I've added the line
numbers.clear();
but i still have the same problem.
I've printed out the numbers list and checked that it is cleared each time but the main list seems to be changed on the first "posability.removeAll(numbers);"
Edit 3:
I've solved it now, The problem was with the ArrayList and Sublists. Once I changed the list so a new ArrayList deepcopy is created rather then just referencing the old one the code works great.
List<List<String>> posabilityGridClone = posabilityGrid.stream().map(it -> new ArrayList(it)).collect(Collectors.toList());
gridRow.addAll((Collection<? extends ArrayList<String>>) (posabilityGridClone.subList(initialIndex, initialIndex+9)));
Add numbers.clear() as the last line of your main cycle. You numbers array is persisted between cycles and it is the problem if I correctly understand what you expect to get.
EDIT
Sorry, I didn't saw numbers at first. I though it was created out of scope.
You problem is actually in this line:
gridRow.addAll((posabilityGrid.subList(initialIndex, initialIndex+9)));
When you create a sublist you have two problems here:
1) Sublist is just a view of the same array. (removing element from sublist affect original list)
2) Elements of array are references to another arrays. So when you run removeAll you actually remove it all from original arrays.
What you need is to make deepcopy of you arrays of arrays and use it instead of original one.
List<List<String>> posabilityGridClone = posabilityGrid.stream().map(it -> new ArrayList(it)).collect(Collectors.toList());
gridRow.addAll((posabilityGridClone.subList(initialIndex, initialIndex+9)));
I'm using the JAVA Driver and am performing a document find.
The returned documents are of type Document.
From the code I can see the String type('name') which comes out correctly.
I can also see the hours array as a string.
What i am looking to do is get a specific element from the array that is to pick out hours[1][2] which would be value 8.
Im trying to do this operation straight on the Document type without converting to a JSONObject.
Is this possible ?
{
"name": "Temp1", "hours": [
[
0,
1,
2,
3,
4,
5
],
[
6,
7,
8,
9,
10,
11
],[
12,
13,
14,
15,
16,
17
] ]
{
FindIterable<Document> iterable = collection.find(and(eq("day", day),eq("month", month),eq("year", year),eq("name", java.util.regex.Pattern.compile("Temp"))));
iterable.forEach(new Block<Document>() {
#Override
public void apply(final Document document) {
//System.out.println(document.toJson());
System.out.println("Name: "+document.getString("name"));
System.out.println("Hours[]: "+document.get("hours"));
}
}
You have to cast it to a DBList object such as :
(BasicDBList) document.get("hours");
You can then iterate over the list just as normal list !
I know there are a lot of questions regarding indices, but none of them solve my problem. I am trying to get a model loaded with diffuse light source into openGl ES and rotate it. I first started with a 3D cube and managed to rotate it. Then i added a light source. That also went without a glitch. Now i'm trying to load a model from it's .obj file and rotate it in place of the cube. I tried two .obj converters but it didn't do the trick for me. Then i created my own .obj importer and the result was the same. I get a distorted image (the lighting and rotation still work on the distorted model). Now i feel that my knowledge about indices might be incomplete.
What I am doing is i am creating a vertexPositionArray[] to store the vertex information and a vertexNormalArray[] to store the corresponding normals with a 1:1 ratio. Now i create an indexArray which stores the order in which the position and the normals should be called.
For eg. if i pass in 3, 5, 6, I am referring to the 3rd, 5th, 6th positions in the vertexPositionArray[] and vertexNormalArray[] both or just the vertexPositionArray?
This is a model that i want to use in my project, and on the sides are the output i am getting
Here is a piece of code that i used to extract the info i wanted from .obj file:
String[] vData={"-1.000000f, 0.000000f, 1.000000f,",
"1.000000f, 0.000000f, 1.000000f,",
"-1.000000f, 0.000000f, -1.000000f,",
"1.000000f, 0.000000f, -1.000000f,",
"0.513184f, 0.000000f, 0.513184f,",
"0.513184f, 0.000000f, -0.513184f,",
"-0.513184f, 0.000000f, -0.513184f,",
"-0.513184f, 0.000000f, 0.513184f,",
"0.158195f, 0.690612f, 0.158195f,",
"0.158195f, 0.690612f, -0.158195f,",
"-0.158195f, 0.690612f, -0.158195f,",
"-0.158195f, 0.690612f, 0.158195f,"};
String[] nData={"-0.889400f, 0.457200f, 0.000000f,",
"0.000000f, -1.000000f, 0.000000f,",
"0.000000f, 1.000000f, 0.000000f,",
"0.889400f, 0.457200f, 0.000000f,",
"0.000000f, 0.457200f, 0.889400f,",
"0.000000f, 0.457200f, -0.889400f,"};
int[] vOrder={8, 12, 11,
6, 5, 3,
7, 6, 1,
8, 7, 2,
5, 8, 4,
11, 12, 9,
6, 10, 9,
5, 9, 12,
7, 11, 10,
7, 8, 11,
1, 6, 3,
2, 7, 1,
4, 8, 2,
3, 5, 4,
10, 11, 9,
5, 6, 9,
8, 5, 12,
6, 7, 10};
int[] nOrder={ 1, 1, 1,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
3, 3, 3,
4, 4, 4,
5, 5, 5,
6, 6, 6,
1, 1, 1,
3, 3, 3,
3, 3, 3,
3, 3, 3,
3, 3, 3,
3, 3, 3,
4, 4, 4,
5, 5, 5,
6, 6, 6,
};
FileWriter write = new FileWriter( path , false);
PrintWriter print_line = new PrintWriter( write );
print_line.println("float[] vertexData ={");
for(int i=0;i<vOrder.length;i++)
{
print_line.println(vData[vOrder[i]-1]);
vCount++;
}
print_line.println("};");
print_line.println("float[] vertexNormal ={");
for(int i=0;i<nOrder.length;i++)
{
print_line.println(nData[nOrder[i]-1]);
}
print_line.println("};");
print_line.println("Vertex Count = "+vCount);
print_line.close();
}
}
I got vData (vertex) and nData (normals) from the obj file by using the replace function in a text editor. Similarly i got the vOrder and nOrder by the data on the faces given below (Adding the number before'//' to vOrder and the one after to nOrder):
f 8//1 12//1 11//1
f 6//2 5//2 3//2
f 7//2 6//2 1//2
f 8//2 7//2 2//2
f 5//2 8//2 4//2
f 11//3 12//3 9//3
f 6//4 10//4 9//4
f 5//5 9//5 12//5
f 7//6 11//6 10//6
f 7//1 8//1 11//1
f 1//3 6//3 3//3
f 2//3 7//3 1//3
f 4//3 8//3 2//3
f 3//3 5//3 4//3
f 10//3 11//3 9//3
f 5//4 6//4 9//4
f 8//5 5//5 12//5
f 6//6 7//6 10//6
Could anyone please tell me what is it I'm doing wrong here?
Thanks in advance. Any help would be appreciated.
if i pass in 3, 5, 6, I am referring to the 3rd, 5th, 6th positions in the vertexPositionArray[] and vertexNormalArray[] both or just the vertexPositionArray?
Both
Do i need to bind my position and normal arrays into 1 array?
No, but you can, not required.
tell me if i understand the .obj file correctly:- f 8//1 5//4 6//3 for this i pushed the vertexPositionArray[7] and vertexNormalArray[0] into a new vertexPArray[] and vertexNArray[], respectively.
Yes, because Obj files're not related to OpenGL at all.
In OpenGL, you can have only one indices array but OBJ files, you can have three types of inces (f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 ....) so you should create your new vertexPArray[] and vertexNArray[] using the faces data.
I dont want the result re-sorted.
Example:
def ids = [7, 9, 5, 6, 12, 2, 10, 1, 42, 13]
result = Project.findAllByIdInList(ids).collect{
projectUtil.createProjectDTO(it)
}
Then if I get the Ids of object created they are sorted this way
result = [1, 2, 5, 6, 7, 9, 10, 12, 13, 42]
I'd like to keep the same order is there a way to achieve that ?
Thanks in advance and sorry for my bad english :)
You could try using getAll instead of findAllByIdInList:
def ids = [7, 9, 5, 6, 12, 2, 10, 1, 42, 13]
result = Project.getAll(ids).collect {
projectUtil.createProjectDTO(it)
}
I just tested it with a similar example in an integration test and it returned the instances in the same order as declared in the list of IDs.
Another option is withCriteria
result = Project.withCriteria {
'in'('id', ids)
}.collect { projectUtil.createProjectDTO(it) }