I just read that it is not possible to define a pointcut on a single array element (bug link). Considering I really need to detect an array element modification, I would like to know if there is any workaround for this kind of problem (a pattern or something).
Something like what is described in this article
public class FieldPointcuts {
static int ar[];
public static void main(String[] args) {
ar = new int[] {100}; //set
ar[0] = 200; //get
}
}
and advice
before(int i, Object s, Object[] a):
arrayset() && args(i, s) && target(a)
{
System.out.println (" Arrayset:["+i+"/"+(a.length-1)+"] = "+s) ;
}
Thanks in advance.
Unfortunately, there is nothing I can think of that will work. The best that I can think of would be to use Lists instead of arrays, but if you are weaving into third party code, this would not be possible.
Related
I want to create a special list data structure that works like an array, in that it's like a list with values x[0], x[1], ... Any advice would be much appreciated.
I know all of my code isn't perfect I just want to figure out how to fix the one problem I've outlined below. This is some of the code I have:
public class SpecialList {
int[] specialList;
int lengthList;
public SpecialList(int x[]) {
this.lengthList = x.length;
this.specialList = new int[lengthList];
this.specialList = x;
for (int i=0; i<lengthList; i++) {
this.specialList[i] = x[i];
}
}
public SpecialList(SpecialList w) {
this.specialList = w.specialList;
}
public SpecialList doSomething(SpecialList y) {
int len = y.lengthList;
//The line below is an example to show the error I get
System.out.println(y[0]);
//Do some other stuff to the list y
return y;
}
//I test the code with this
public static void main(String[] args) {
SpecialList y = new SpecialList(new int[] {14, 17, 30});
SpecialList z = x.doSomething(y);
}
However I get the error 'array required, but SpecialList found' when I try to do stuff with y[i] like with System.out.println(y[0]); line of code.
'lengthList' works but getting the individual values of y[i] , the list doesn't. I cant work out whats wrong with my constructor for it to not work how I want it to.
You can't redefine what [n] means based on what object it's applied to; that's an array-specific notation. So y[0] where y is a SpecialList instance just won't work. If it could work, List (or at least ArrayList or other implementions where direct addressing is cheap) would probably have that feature.
Although you can do that in some other languages, you can't in Java. It's just not a feature Java offers. (Which is a good thing or a bad thing depending on your point of view...) Instead, you'll have to provide get and set methods or similar, just like List does.
I'm trying to write an operation that can enumerate all the combinations of a set of N elements. In other words, the N is unknown and depends on user input. On receiving the N, the function should be able to give all the possible combination of an N-item set, with all elements from a set U. Say, U={A,B,C...J}, 10 elements in total.
One more example of what I need, the function enumerate(3) should tell me all the possible combinations like {A,B,C},{A,D,J} etc., using elements picked from U.
I tried to do this in a way using for loops(initializing an integer since the size of U happen to be 10 in this case, so I can use 123 to denote {A,B,C}...). But the code smells bad and I'd like to know how this can be done in a more elegant with using recursive calls.
Java/Groovy are both acceptable (because I'm trying in them too). If anybody could provide ideas how to do this with closures in Groovy it'll be even more appreciated.
Also please don't use integers to denote the combination as I did, because I think this only applies to a certain U with no generality.
Thanks!
I believe I have the solution.
import java.util.HashSet;
import java.util.Set;
public class Generator<T> {
Set<T> source;
Set<Set<T>> combinations;
public Generator(Set<T> source) {
this.source = source;
}
public static void main(String[] args) {
final Set<String> source = new HashSet<>();
for (char character = 'A'; character <= 'Z'; character++){
source.add(String.valueOf(character));
}
final Generator<String> stringGenerator = new Generator<>(source);
stringGenerator.generate(3);
}
public void generate(int size){
if (size == 0){
return;
}
Set<Set<T>> newCombinations = new HashSet<>();
for (T element : source) {
if (combinations == null || combinations.isEmpty()){
final HashSet<T> set = new HashSet<>();
set.add(element);
newCombinations.add(set);
} else {
for (Set<T> combination : combinations) {
final HashSet<T> newCombination = new HashSet<>(combination);
if (newCombination.add(element)) {
newCombinations.add(newCombination);
}
}
}
}
combinations = newCombinations;
generate(size - 1);
}
}
It was fast dirty implementation, so probably it misses some cases, but it generally demonstrates the idea with at least one working case.
My professor gave me a code for the methods to be used in sorting an array of names lexicographically, but I have no idea how what to write inside the main class to show that the program works. I am very new to java, so please if you know how to do this could you write it as simple as possible for me to understand it. Thanks in advance.
This is are the classes
public class quicksort_class {
int[] array1 = new int[11];
public quicksort_class(int[] w)
{
array1 = w;
}
private static void sort(String[] string, int leftlimit, int rightlimit) {
if (rightlimit > leftlimit)
{
int midpoint = partitionstep(string, leftlimit, rightlimit);
sort(string, leftlimit, midpoint - 1);
sort(string, midpoint, rightlimit);
}
}
public static int partitionstep(String[] string, int leftlimit, int rightlimit)
{
String midpoint = string[rightlimit];
int lpointer = leftlimit;
int rpointer = rightlimit;
String temp = "";
while(string[lpointer].compareTo(midpoint) <= 0)
{
lpointer = lpointer ++;
}
while(string[rpointer].compareTo(midpoint) > 0)
{
rpointer = rpointer --;
}
if(lpointer > rpointer)
{
temp = string[lpointer];
string[lpointer] = string[rightlimit];
string[rpointer] = temp;
System.out.println(string);
}
while(lpointer < rpointer)
{
temp = string[lpointer];
string[lpointer] = string[rightlimit];
string[rightlimit] = temp;
}
return lpointer;
}
}
This is the main class (as you can see I have no idea what to write)
package quicksort;
public class Quicksort {
public static void main(String[] args) {
}
}
Write something that sets up an array of strings and calls sort against it, then prints out the results or checks them against a known good result.
Ideally, write something which does this repeatedly, with particular emphasis on checking unusual combinations (already sorted or sorted in reverse, null in the array, same value appearing several times or all values being identical...)
If you want to go beyond that, you need to dig into the code to understand its edge cases and specifically test those, and/or do a "code coverage" analysis (there are tools to help with that) to make sure all parts of the code have been exercised.
Assume the algorithm of sort method is correct:
1. If the main method is within the body of quicksort_class, you can directly call the sort method as sort(arrayToBeSorted, 0 , arrayToBeSorted.length-1). And the arrayToBeSorted should ordered lexicographically after your call. You can check that to confirm.
2. If the main method is in other class, as your main method currently, you need to at least change the private prefix of sort method to public, and call quicksort_class.sort(arrayToBeSorted, 0 , arrayToBeSorted.length-1).
Some tips:
1. Private prefix of method definition means this method can only be called inside current class body.
2. Static prefix of method definition means you should call this method via class name directly, instead of via a instance of class.
By the way, can you provide what the array1 attribute stands for? I don't get why it's there.
Maybe this is trivial question for experienced programmers but i wonder if there is any significant performance difference (with big or very big amount of data in collection) between two difference approaches of passing variables?
I've made a tests but with rather small data structures and i don't see any significant differences. Additionally i am not sure if these differences aren't caused by interferences from other applications run in background.
Class with collection:
public class TestCollection
{
ArrayList<String[]> myTestCollection = new ArrayList<String[]>();
public TestCollection()
{
fillCollection();
}
private void fillCollection()
{
// here is fillng with big amount of data
}
public ArrayList<String[]> getI()
{
return myTestCollection;
}
}
And methods that operate on collection:
public class Test
{
static TestCollection tc = new TestCollection();
public static void main(String[] args)
{
new Test().approach_1(tc);
new Test().approach_2(tc.getI());
}
public void approach_1(TestCollection t)
{
for (int i = 0; i < tc.getI().size(); i++)
{
// some actions with collection using tc.getI().DOSOMETHING
}
}
public void approach_2(ArrayList<String[]> t)
{
for (int i = 0; i < t.size(); i++)
{
// some actions with collection using t.DOSOMETHING
}
}
}
Regards.
No, there is no real difference here.
Java passes object references to methods, not copies of the entire object. This is similar to the pass by reference concept in other languages (although we are actually passing an object reference to the called method, passed by value).
If you come from a C programming background it's important to understand this!
And, some tips - firstly, it's better practise to declare your list as List<...> rather than ArrayList<...>, like this:
List<String[]> myTestCollection = new ArrayList<String[]>();
And secondly, you can use the improved for loop on lists, like this:
// first case
for (String[] s : tc.getI()) { /* do something */ }
// second case
for (String[] s : t) { /* do something */ }
Hope this helps :)
I'm fairly confident that there's no way this could work, but I wanted to ask anyway just in case I'm wrong:
I've heard many times that whenever you have a certain number of lines of very similar code in one batch, you should always loop through them.
So say I have something like the following.
setPos1(getCard1());
setPos2(getCard2());
setPos3(getCard3());
setPos4(getCard4());
setPos5(getCard5());
setPos6(getCard6());
setPos7(getCard7());
setPos8(getCard8());
setPos9(getCard9());
setPos10(getCard10());
setPos11(getCard11());
setPos12(getCard12());
There is no way to cut down on lines of code as, e.g., below, right?
for (i = 0; i < 12; i++) {
setPos + i(getCard + i)());
}
I'm sure this will have been asked before somewhere, but neither Google nor SO Search turned up with a negative proof.
Thanks for quickly confirming this!
No way to do that specifically in Java without reflection, and I don't think it would be worth it. This looks more like a cue that you should refactor your getcard function to take an integer argument. Then you could loop.
This is a simple snippet that shows how to loop through the getters of a certain object to check if the returned values are null, using reflection:
for (Method m : myObj.getClass().getMethods()) {
// The getter should start with "get"
// I ignore getClass() method because it never returns null
if (m.getName().startsWith("get") && !m.getName().equals("getClass")) {
// These getters have no arguments
if (m.invoke(myObj) == null) {
// Do something
}
}
}
Like the others stated, probably it's not an elegant implementation. It's just for the sake of completeness.
You could do it via reflection, but it would be cumbersome. A better approach might be to make generic setPos() and getCard() methods into which you could pass the index of the current item.
You need to ditch the getter/setter pairs, and use a List to store your objects rather then trying to stuff everything into one God object.
Here's a contrived example:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Foo {
public static class Card {
int val;
public Card(int val) {
this.val = val;
}
public int getVal() {
return val;
}
}
public static class Position {
int value;
public Position(Card card) {
this.value = card.getVal();
}
}
public static void main(String[] args) {
List<Card> cards = new ArrayList<Card>(Arrays.asList(new Card(1), new Card(2), new Card(3)));
List<Position> positions = new ArrayList<Position>();
for (Card card : cards) {
positions.add(new Position(card));
}
}
}
You can't dynamically construct a method name and then invoke it (without reflection). Even with reflection it would be a bit brittle.
One option is to lump all those operations into one method like setAllPositions and just call that method.
Alternatively, you could have an array of positions, and then just loop over the array, setting the value at each index.
Card[] cardsAtPosition = new Card[12];
and then something like
public void setCardsAtEachPosition(Card[] valuesToSet) {
// check to make sure valuesToSet has the required number of cards
for (i = 0; i < cardsAtPosition.length; i++) {
cardsAtPosition[i] = valuesToSet[i];
}
}
Reflection would be your only option for your example case.