I want to draw a String value from otherclass2. How can I do this?
public class Main {
public static void main(String[] args) {
List<otherclass> list = new ArrayList<otherclass>();
list.add(new otherclass());
}
}
public class otherclass {
private Map<String, otherclass2> maps = new HashMap<String, otherclass2>();
}
public class otherclass2 {
String value = "I want this String";
}
Should I use list.get()? Or is there another approach?
You can not get the value of otherclass2 because your list contain instance of otherclass and the otherclass is have a private maps => so that from the list.get(0) you can not access the maps => can not access maps also mean you can not access otherclass2 value.
Second problem is that you have not init otherclass2 and put it into maps.
To solve you problem (you should create get/setter instead of use public like here):
public class Main {
public static void main(String[] args){
List<otherclass> list = new ArrayList<otherclass>();
list.add(new otherclass());
otherclass other = list.get(0);
String your_value = other.maps.get("first").value;
System.out.println(your_value);
}
}
public class otherclass{
public Map<String, otherclass2> maps = new HashMap<String, otherclass2>();
public otherclass(){
maps.put("first", new otherclass2());
}
}
public class otherclass2{
public String value = "I want this String"
}
Related
I have successfully obtained the values of List field from another class using reflection. However, I can't use it if the field is of type List.
Here's my actual code:
class PageModel {
#FindAll({ #FindBy(xpath = "//select") })
public static List<WebElement> webelements;
public static List<String> strings = Arrays.asList("One", "Two", "Three");
}
class Test {
public static void main(String[] args) {
Class model = Class.forName("PageModel");
// List<String> sample
obj = model.getField("strings").get(model);
List<Object> testStrings = (List<Object>) obj;
for (Object str : testStrings)
System.out.print(str);
// List<WebElement> sample
obj = model.getField("webelements").get(model);
List<Object> testElements = (List<Object>) obj;
// java.lang.reflect.Field cannot be cast to java.util.List
}
}
Even when I directly use List testElements = (List) obj; , the same error java.lang.reflect.Field cannot be cast to java.util.List is returned.
Thank you so much in advance.
You can get the list by using classname by making them as static.
Here, I have modified your code.
public class MyGetter {
sourceClass;
public MyGetter(String sourceName) {
sourceClass = Class.forName(sourceName);
}
public List<String> getField(String fieldName) {
return new ArraysourceClass.getField(fieldName);
}
}
public class Source1 {
public static List<String> field1 = new ArrayList<String>(){{
field1.add("field1Val");
}};
}
public class Source2 {
public static List<String> field2 = new ArrayList<String>(){{
field2.add("field2Val");
}};
}
public class Test {
public void main(String[] args){
MyGetter get1 = new MyGetter("Source1");
System.out.println(get1.field1);
// output: field1Val
MyGetter get2 = new MyGetter("Source2");
System.out.println(get2.field2);
// output: field2Val
}
}
I have the following class:
public final class FileNames
{
private FileNames()
{}
public static final String A = "a.csv";
public static final String B = "b.csv";
public static final String C = "123.csv";
...
}
Now I want to get all String values from the above, somewhere in a different class.Output can be as a String array or ArrayList Or any other Collection. I am using jdk 1.7. No clue how to proceed with this as the list of Strings can be increased,i.e. may add "D","E" etc..
Reflection is your friend :)
public class Sample {
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
Class<FileNames> clazz = FileNames.class;
Field[] arr = clazz.getFields(); // Get all public fields of your class
for (Field f : arr) {
if (f.getType().equals(String.class)) { // check if field is a String
String s = (String)f.get(null); // get value of each field
// add s to a List
System.out.println(s);
}
}
}
}
final class FileNames {
private FileNames() {
}
public static final String A = "a.csv";
public static final String B = "b.csv";
public static final String C = "123.csv";
}
O/P :
a.csv
b.csv
123.csv
You add this function:
public static ArrayList<String> getFilenames() {
ArrayList<String> filenames = new ArrayList<String>;
filenames.add(A);
filenames.add(B);
filenames.add(C);
return filenames;
}
Then you can use this function somewhere like:
ArrayList<String> filenames = new ArrayList<String>;
filenames = Filenames.getFilenames();
String filenameA = filenames.get(0); // to retrieve the first element (A)
String filenameB = filenames.get(1); // to retrieve the second element (B)
// and so on...
If you want to add more and convert it in an auto way you can check this: Java method with unlimited arguments
I hope I could help you.
Consider I am given an array of Classes and string representation of an Object. How can I get which Class this Object belongs to?
I thought of this approach but I don't know how to achieve it:
Iterating over Class array and then getting all instances of that
class.Then convert each instance to its String representation and then
check if it equals given String.
The problem I'm having is how do I get all Instances of that Class?
We can use getInstance() if all are Singleton class but what if not?
Please clarify my if I have any misunderstanding.
import java.util.*;
public class Class_instance {
public static void main(String args[]){
List<Class> class_list = new ArrayList<Class>();
Test_class x = new Test_class();
Test y = new Test();
class_list.add(x.getClass());
class_list.add(y.getClass());
String ex = x.toString();
}
}
How to know what class ex represents here?
Short answer - no, this won't work.
The toString() method returns a textual representation of the object, but there is no guarantee this will include the class name. For example, for Strings, toString() returns the value of the string. In particular any textual representation could come from a string.
If you have a specific list of classes you want to look for (and they have identifiable values), you could write regexes which would identify their toString values.
Using the Class object directly is more likely to be what you're after here:
public static void main(String [] args){
Class[] possibleClasses= {String.class, Integer.class};
System.out.println(identifyClass("string", possibleClasses));
System.out.println(identifyClass(4, possibleClasses));
}
#SuppressWarnings("raw")
public static Class identifyClass(Object o, Class[] possibleClasses){
// Ignore null inputs
if (o==null){
return null;
}
// Find the first entry which matches o
for (Class c : possibleClasses){
if (c.isInstance(o)){
return c;
}
}
// If no matches are found, return null.
return null;
}
Although that said, maybe this would be enough?
System.out.println(ex.getClass().getName());
As mentioned we need to know what string representation means.
In most application (AFAIK) instanceof should suffice to check if object belong to a certain class or not . Another way is to define a overwrite the toString method
public class House {
public String address;
public String type;
public House(String add){
this.address = add;
}
#Override
public String toString() {
return (address + "-" + type) ;
}
}
If given a String sample = "Hogwart-Castle"; You can use the following :
houseObj.toString().equals(sample);
If you own the classes you want to search, you can keep the track of their instances by creating a new class (I called it MyObject) with a static field that you fill when a new object of that class is created, and then extending the classes you want to keep track with this new class.
public class MyObject {
private static Map<Class<?>, List<WeakReference<?>>> instances = new HashMap<>();
public MyObject() {
if (!instances.containsKey(getClass())) {
instances.put(getClass(), new ArrayList<>());
}
instances.get(getClass()).add(new WeakReference<>(this));
}
public static List<Object> getInstances(List<Class<?>> classes) {
List<Object> result = new ArrayList<>();
for (Class<?> clazz : classes) {
if (instances.containsKey(clazz)) {
Iterator<WeakReference<?>> iterator = instances.get(clazz).iterator();
while (iterator.hasNext()) {
WeakReference<?> ref = iterator.next();
if (ref.get() == null) {
iterator.remove();
} else {
result.add(ref.get());
}
}
}
}
return result;
}
}
Then you can use it like this:
public class Main {
public static void main(String[] args) {
Dog d1 = new Dog("I'm a dog");
Dog d2 = new Dog("I'm an animal");
Cat c1 = new Cat("I'm an animal");
List<Class<?>> classList = new ArrayList<>();
classList.add(Dog.class);
find("I'm an animal", classList); // Found a Dog
classList.add(Cat.class);
find("I'm an animal", classList); // Found a Dog and a Cat
find("I'm a dog", classList); // Found a Dog
}
private static void find(String str, List<Class<?>> classes) {
for (Object o : MyObject.getInstances(classes)) {
if (o.toString().equals(str)) {
System.out.println("Found a " + o.getClass().getSimpleName());
}
}
}
}
My Dog class (and similarly the Cat class) looks like this:
public class Dog extends MyObject {
String description;
public Dog(String description) {
this.description = description;
}
#Override
public String toString() {
return description;
}
}
Beware that toString() doesn't return a unique representation of an object (as shown in my example), unless you have full control over the toString() of that objects and you ensure it yourself.
I have a following scenario:
public class MapTest {
String name = "guru";
/**
* #param args
*/
public static void main(String[] args) {
MapTest mapTest = new MapTest();
Map map = new HashMap();
map.put("name", mapTest.name);
System.out.println(mapTest.name);
map.put("name", "raj");
System.out.println(mapTest.name);
}
}
output is:
guru
guru
is there any way that I can get the output as
guru
raj
ie. I want the HashMap map and the member variable name to in sync.
Thanks.
You can't do that. That's not the way Java works. When you write:
map.put("name", mapTest.name);
that's putting the current value of mapTest.name into the map. After the argument has been evaluated, it's completely independent of the original expression.
If you need to do something like this, you would have some sort of mutable wrapper class - you'd put a reference to the wrapper into the map, and then you can change the value within the wrapper, and it doesn't matter how you get to the wrapper, you'll still see the change.
Sample code:
import java.util.*;
class StringWrapper {
private String value;
StringWrapper(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
#Override
public String toString() {
return value;
}
}
public class Test {
public static void main(String[] args) throws Exception {
Map<String, StringWrapper> map = new HashMap<String, StringWrapper>();
StringWrapper wrapper = new StringWrapper("Original");
map.put("foo", wrapper);
System.out.println(map.get("foo"));
wrapper.setValue("Changed");
System.out.println(map.get("foo"));
}
}
You appear to be confused about how maps work. For a better idea, try printing out the map.
map.put("name", mapTest.name);
System.out.println(map);
map.put("name", "raj");
System.out.println(map);
You will get:
{"name"="guru"}
{"name"="raj"}
Note that mapTest.name == "guru" always as you never modify it.
Java maps just don't support anything like this. When you do
map.put("name", mapTest.name);
You put a reference to the object referenced by mapTest.name in the map. When you do
map.put("name", "raj");
You put a reference to the new String object in the map. The reference to mapTest.name isn't in the map anymore.
Out of curiosity, why don't you want to just use map.get("name")?
If you want something to be performed dynamically, you should use a function/method.
public class MapTest {
private final Map<String, String> map = new HashMap<String, String>();
public String name() {
return map.get("name");
}
public static void main(String[] args) {
MapTest mapTest = new MapTest();
mapTest.map.put("name", "guru");
System.out.println(mapTest.name());
mapTest.map.put("name", "raj");
System.out.println(mapTest.name());
}
}
prints
guru
raj
I'm obviously missing something here, as this sound basic enough but yet...
I have a collection of objects . I need to use each one of them as parameter in constructor for a new object and return each new object to the caller method, one by one.
But -if I loop over the collection obviously the loop only runs once, and only returns the 1st object.
Edit : Returning the whole collection or some new collection will not work because :
The caller method [not mine to change] runs inside a start() method of a Runnable ThingProvider, which returns a single Thing whenever a request is submitted to it. So, returning List is not possible.
Thanks :)
public List<T> loop(Collection<? extends U> coll) {
List<T> a = new ArrayList<T>();
for (U u : coll){
a.add(new T(u));
}
return a;
}
Return a custom Iterator. Assumming your new objects are of class MyObject and the constructor accepts an Object:
public Iterator<MyObject> myObjectsIterator(final Iterator<? extends Object> it) {
return new Iterator<MyObject>() {
public boolean hasNext() {
return it.hasNext();
}
public MyObject next() {
return new MyObject(it.next());
}
public void remove() {
it.remove();
}
};
}
And you would call it like this:
...
Iterator<MyObject> myIt = myObjectsIterator(myListOfObjects.iterator());
// Now you can pass myIt around as a normal object. It will remember
// which one is the next Object with which to construct a MyObject
// and will generate it on the fly
...
while (myIt.hasNext()) { // is there any MyObject remaining?
MyObject myObj = myIt.next(); // gets the next MyObject
// do something with myObj
}
...
This is a poorly worded question and I think as others have noted, just returning a new list of the objects is fine. But if you really want to process them one at a time while you're looping through it, you can use the command pattern.
public interface Command {
void execute(NewType object);
}
Now in your caller method, you can do the following:
public void doSomething() {
processList(myList, new Command() {
void execute(NewType object) {
// Do whatever you want with this object
}
});
}
And, in the method that will actually go through the list:
public void processList(Iterable<OldType> values, Command command) {
for(OldType v : values) {
NewType newType = new NewType(v);
command.execute(newType);
}
}
In java you can return only once. So if you want to get some informations from your methods either you wrap them into a "Big" Object (here a List) or you give to the method the means to put informations in your parameters.
You could have something like this :
public static void main(String... args){
List<Parameter> parameters = methodToGetParameters();
List<Result> results = generateObjectsFromList(parameters);
for(Result result : results){
handleAResult(result);
}
}
public List<Result> generateObjectsFromList(List<Parameter> parameters){
List<Result> results = new ArrayList<Result>();
for(Parameter parameter : parameters){
results.add(new Result(parameter));
}
return results;
}
Or like this :
public static void main(String... args){
List<Parameter> parameters = methodToGetParameters();
List<Result> results = new ArrayList<Result>();
generateObjectsFromList(parameters, results);
for(Result result : results){
handleAResult(result);
}
}
public void generateObjectsFromList(List<Parameter> parameters, List<Result> results){
for(Parameter parameter : parameters){
results.add(new Result(parameter));
}
}
A third way to do this would be to use fields, but it's not really good to have a lot of fields if they're not really used (or only by one method).
On the same topic :
Java Object Oriented Design Question: Returning multiple objects in java(Updated)
Using a java method to return multiple values?
Return a collection from the method and in the collection implement a custom iterator to transform the input collection to the new collection. The following code shows how to do it using the Google Guava library:
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
public class Test {
static class Person {
public final String name;
public Person(String name) {
this.name = name;
}
}
public static Collection<Person> peopleFromNames(Collection<String> names) {
return Collections2.transform(names, new Function<String, Person>() {
public Person apply(String name) {
return new Person(name);
}});
}
public static void main(String[] args) {
List<String> names = Arrays.asList("Brian", "Albert", "Roger");
for (Person person : peopleFromNames(names)) {
System.out.println(person.name);
}
}
}
do you mean using of delegates something like below
public class Test {
private static class Person{
private final String name;
Person(String name){
this.name = name;
}
#Override
public String toString() {
return return name;
}
}
private interface Printer {
void print(Object object);
}
public static void main(String[] args) {
final String[] names = {"one", "two", "three"};
final ArrayList<Person> people = construct(names, new Printer() {
#Override
public void print(Object object) {
System.out.println(object.toString());
}
});
}
private static ArrayList<Person> construct(String[] names, Printer printer) {
ArrayList<Person> people = new ArrayList<Person>();
for (String name : names) {
printer.print(new Person(name));
}
return people;
}
}
It's Possible.
Check these Project for Java-yield , yield4Java, infomancers
If you're using this just once in your entire code, You're better off choosing a method from the other answers.
Return a list of the new objects.