Matching of the Parameters in Vectors - java

I am trying to Learn Java as I am a beginner and recently i fumbled upon Vectors and Lists in Java. This is a very simple and a basic question, but any help would be really helpful for a learner.
I have created a vector v as shown below:
public vector createVector(){
Vector v = new Vector();
v.add(Path1); //Path1 is the path of a directory
v.add(Path2);
return v;
}
I have a function in which I pass, one of the parameter is v.get(i). The function is shown below:
for(int i=0,i<v.size(),i++){
qlm("Write", "init",getList(),**v.get(i)**); // Function call.
}
Function declaration is :
Void qlm(String Option, String init, List lists, **String paths**){
}
I am not able to match the parameter in the function call which is v.get(i) with String Paths. Please share your knowledge.
Thanks a lot.

Without Generics, v.get(i) will always return an object. Here are two ways to resolve it:
Declare Vector as
Vector< String > v = new Vector< String > ();
Or do
v.get(i).toString();
But before doing v.get(i).toString(), null check should be performed on v.get(i).

try this
for(int i=0,i<v.size(),i++){
qlm("Write", "init",getList(),v.get(i).toString()); // Function call.
}

Typically, in Java, when somebody declares a Vector they will declare it using Generics. To declare a Vector that will contain strings, you would write this:
Vector<String> myVector = new Vector<String>();
Then, to get a iterate over it's values, you would do this:
for(int i = 0; i < myVector.size(); i++){
String s = myVector.get(i); // The get() method here returns a String instead of Object
}
Or, because Vectors are enumerable, you could do this:
for(String s : myVector){
// There is now a variable named s available in the loop that
// will contain each element in the vector in turn.
}
That being said, you really shouldn't use Vectors any more. They are pretty old, and there are better lists available in Java. I would recommend that you use an ArrayList, but they're a variety of lists available which can be found here under "All known implementing classes."
To rewrite your example using generics and an ArrayList, you would do this:
List<String> myList = new ArrayList<String>();
myList.add(Path1);
myList.add(Path2);
for(String s : myList){
qlm("Write", "init", getList(), s);
}

Related

How to simulate Pythons's dict "items()" method for Java's HashMaps?

I know I should learn how to program efficiently in Java and stop thinking it is Python; but the problem is that this kind of thing is turning out to be a small nightmare in Java.
I have the following function in Python that takes a string as an argument:
def decodeL(input):
L = []
for i in range(len(input)):
for j in x.items(): // Where "x" is the Dictionary outside the function.
if input[i].lower() in j[0]:
L.append(j[1])
return L
Ignoring the functionality of the function itself, what makes it work so well is the "items()" method, which returns me tuples inside of a list. As you can see, I play with these tuples acessing its own indexes.
In Java this is a very unpleasant problem.
static ArrayList items(HashMap hashTarget) {
ArrayList L = new ArrayList();
Set<String> keys = hashTarget.keySet();
Collection<Object> values = hashTarget.values();
for (int i = 0; i < hashTarget.size(); i++) {
L.add(keys);
L.add(values);
}
return L;
}
As you can see, I tried to implement my own "items()" method and I failed miserably; since there is no tuples natively in Java, this is really messing up with my brain :). I can't intercalate the keys and values in the same way that Python does so beautifully; therefore, I can't create the Java Version of that "decodeL" function, which is my final goal.
So, that's it; another random "challenge" for you guys.
Java has already implemented this for you in the way of the Map.entrySet() method.
for(Map.Entry<K, V> j : x.entrySet()) {
V val = j.getValue(); // j[1]
K key = j.getKey(); // j[0]
}

How to convert a List of String arrays to a List of objects

I want to convert a List to a List so that each object on my new list includes the first element of each String[].
Do you know if this is possible to do in java?
for example:
public List<String[]> readFile(){
String[]array1={"A","1.3","2.4","2.3"};
String[]array2={"B","1.43","3.4","2.8"};
String[]array3={"C","5.23","2.45","2.9"};
List<String[]>ReadFile= new ArrayList<String[]>();
ReadFile.add(array1);
ReadFile.add(array2);
ReadFile.add(array3);
return ReadFile;
}
Now I want a method which will take the List ReadFile from above to somehow split the arrays of strings into an ID which will be the first element "A", "B", "C" and another part which would be the string array of numbers which I will put through another method to convert numbers from String to type Double. I have already got the method to convert to double but I need to be able to keep track of the ID field because the ID field will be used to identify the array of numbers.
A friend suggested that I create an Object where each objects has one part as a String ID and the other part as an array. That is the part which I do not know how to do.
Can anybody help please?
below is the method declaration which I believe I should have so the return type will be List where each array has been converted to an Object with two parts.
public List<Object> CreateObject(List<String[]>ReadFile){
}
Thanks,
Jetnori.
Hi all, Thank you for taking your time to help.
I can see the benefit of using HashTables. I am as of now trying to implement it. I know i might be sidetracking a little but just to explain what I am trying to do:
In my project I have CSV file with data about gene expression levels. The method that I use from OpenCSV to read the file returns a List(String[]) where each String[] is one row in the file. The first element of each row is variable name (recA, ybjE etc). The rest of the row will be numbers data related to that variable. I want to calculate Pearson's correlation between each of the number arrays. The method which I have got implemented already does that for me but the problem that I have now is that I had to remove the string values from my arrays before I could convert to double by iterating over the array. After I have managed to calculate the correlation between each array of doubles by still keeping the ID linked to the row, I want to be able to draw an undirected node graph between the genes that have a correlation higher than a threshold which I will set (for example correlation higher than 0.80). I don't know if i am biting more than i can chew but I have 30 days to do it and I believe that with the help of people like you guys I will get through it.
Sorry for going on for a bit.
thanks,
Jetnori.
I agree with the answer Alb provided, however this is what your friend has suggested, first you need a class to represent the data. I have included a constructor that parses the data and one that accepts already parsed data, depending on how you like to think of things.
public class NumberList {
private double[] numbers;
private String key;
public NumberList(Strig key, double[] numbers){
this.ley = key;
this.numbers = numbers;
}
public NumberList(String[] inputList) {
key = inputList[0];
numbers = new double[inputList.length-1];
for(int i=1;i<inputList.length;i++){
numers[i-1] = Double.parseDouble(inputList[i]);
}
}
public String getKey() {
return key;
}
public double[] getNumbers() {
return numbers;
}
}
Then you need your function to generate the list:
public List<NumberList> CreateObject(List<String[]> ReadFile){
ArrayList<NumberList> returnList = new ArrayList<NumberList>(ReadFile.size());
for (String[] input : ReadFile) {
returnList.add(new NumberList(input));
}
return returnList;
}
Note this uses the constructor that parses the data, if you use the other constructor then the "CreateObject" function would need to include the parsing logic.
Finally on a side note the standard convention in java is that the only thing that is capitalized are class names and final static fields (which appear in all caps sepearted by underscores), so conventionally the method signature would be:
public List<NumberList> createObject(List<String[]> readFile){
...
}
Sounds like you need a Map instead of a List, it lets you index things by a key (in your case ID).
Map<String, String[]> map = new Hashmap<String, String[]>();
for( String[] array : ReadFile ){
map.put( array[0], array );
}
then to get the array of values for 'A' you would do:
String[] values = map.get( "a" );
If you want the values to be doubles instead of strings you'll want to change the array before putting it (the map.put call) I'd advise using a list or other collections instead of an array also. You also will probably also want to remove the ID part from these values, which my code does not do.
public class Split_ListwithIDs {
Hashtable<String, String[]> table = new Hashtable<String, String[]>();
Splitter spl ;
public Split_ListwithIDs(Splitter split){
spl = split;
}
private void addEntry(String key , String[] vals){
table.put(key, vals);
}
public void parseList(List<String[]> list){
for(String[] entry : list){
String[] temp = new String[entry.length - 1];
System.arraycopy(entry, 1, temp, 0,entry.length - 1);
addEntry(entry[0], spl.GetStringArrayOfNumbers(temp));
}
}
class SplittingHelper implements Splitter{
#Override
public String[] GetStringArrayOfNumbers(String[] arr) {
String[] strArray = null ;
// implementation here
return arr;
}
}
interface Splitter {
String[] GetStringArrayOfNumbers(String[] arr);
}
}
You will have to use a Hashtable instead of a list of objects.( I am assuming that you will need to search through the list for a given entry using the First alphabet as key - This will be very laborious if you want to use a List ).
In the method SplittingHelper , provide your custom logic to parse the string of numbers and return another string[] of numbers.
I don't understand your goal, but for 'an object with 2 parts' you might consider storing them in a Hashtable: http://download.oracle.com/javase/6/docs/api/java/util/Hashtable.html

Java: Apply Callback to Array Values

I'm looking for a simple way to apply a callback method to each element in a String array. For instance in PHP I can make all elements in an array like this:
$array = array_map('strtolower', $array);
Is there a simple way to accomplish this in Java?
First, object arrays in Java are vastly inferior to Lists, so you should really use them instead if possible. You can create a view of a String[] as a List<String> using Arrays.asList.
Second, Java doesn't have lambda expressions or method references yet, so there's no pretty way to do this... and referencing a method by its name as a String is highly error prone and not a good idea.
That said, Guava provides some basic functional elements that will allow you to do what you want:
public static final Function<String, String> TO_LOWER =
new Function<String, String>() {
public String apply(String input) {
return input.toLowerCase();
}
};
// returns a view of the input list with each string in all lower case
public static List<String> toLower(List<String> strings) {
// transform in Guava is the functional "map" operation
return Lists.transform(strings, TO_LOWER);
}
Unlike creating a new array or List and copying the lowercase version of every String into it, this does not iterate the elements of the original List when created and requires very little memory.
With Java 8, lambda expressions and method references should finally be added to Java along with extension methods for higher-order functions like map, making this far easier (something like this):
List<String> lowerCaseStrings = strings.map(String#toLowerCase);
There's no one-liner using built-in functionality, but you can certainly match functionality by iterating over your array:
String[] arr = new String[...];
...
for(int i = 0; i < arr.length; i++){
arr[i] = arr[i].toLowerCase();
}
You could use reflection:
String[] map(java.lang.reflect.Method method, String[] array) {
String[] new_array = new String[array.length];
for (int i = 0; i < array.length; i++) new_array[i] = (String)method.invoke(null, new Object[]{array[i]});
return new_array;
}
Then you just need to declare a static method somewhere and get a reference to it using the reflection API.

How to lowercase every element of a collection efficiently?

What's the most efficient way to lower case every element of a List or Set?
My idea for a List:
final List<String> strings = new ArrayList<String>();
strings.add("HELLO");
strings.add("WORLD");
for(int i=0,l=strings.size();i<l;++i)
{
strings.add(strings.remove(0).toLowerCase());
}
Is there a better, faster way? How would this example look like for a Set? As there is currently no method for applying an operation to each element of a Set (or List) can it be done without creating an additional temporary Set?
Something like this would be nice:
Set<String> strings = new HashSet<String>();
strings.apply(
function (element)
{ this.replace(element, element.toLowerCase();) }
);
Thanks,
Yet another solution, but with Java 8 and above:
List<String> result = strings.stream()
.map(String::toLowerCase)
.collect(Collectors.toList());
This seems like a fairly clean solution for lists. It should allow for the particular List implementation being used to provide an implementation that is optimal for both the traversal of the list--in linear time--and the replacing of the string--in constant time.
public static void replace(List<String> strings)
{
ListIterator<String> iterator = strings.listIterator();
while (iterator.hasNext())
{
iterator.set(iterator.next().toLowerCase());
}
}
This is the best that I can come up with for sets. As others have said, the operation cannot be performed in-place in the set for a number of reasons. The lower-case string may need to be placed in a different location in the set than the string it is replacing. Moreover, the lower-case string may not be added to the set at all if it is identical to another lower-case string that has already been added (e.g., "HELLO" and "Hello" will both yield "hello", which will only be added to the set once).
public static void replace(Set<String> strings)
{
String[] stringsArray = strings.toArray(new String[0]);
for (int i=0; i<stringsArray.length; ++i)
{
stringsArray[i] = stringsArray[i].toLowerCase();
}
strings.clear();
strings.addAll(Arrays.asList(stringsArray));
}
You can do this with Google Collections:
Collection<String> lowerCaseStrings = Collections2.transform(strings,
new Function<String, String>() {
public String apply(String str) {
return str.toLowerCase();
}
}
);
If you are fine with changing the input list here is one more way to achieve it.
strings.replaceAll(String::toLowerCase)
Well, there is no real elegant solution due to two facts:
Strings in Java are immutable
Java gives you no real nice map(f, list) function as you have in functional languages.
Asymptotically speaking, you can't get a better run time than your current method. You will have to create a new string using toLowerCase() and you will need to iterate by yourself over the list and generate each new lower-case string, replacing it with the existing one.
Try CollectionUtils#transform in Commons Collections for an in-place solution, or Collections2#transform in Guava if you need a live view.
This is probably faster:
for(int i=0,l=strings.size();i<l;++i)
{
strings.set(i, strings.get(i).toLowerCase());
}
I don't believe it is possible to do the manipulation in place (without creating another Collection) if you change strings to be a Set. This is because you can only iterate over the Set using an iterator or a for each loop, and cannot insert new objects whilst doing so (it throws an exception)
Referring to the ListIterator method in the accepted (Matthew T. Staebler's) solution. How is using the ListIterator better than the method here?
public static Set<String> replace(List<String> strings) {
Set<String> set = new HashSet<>();
for (String s: strings)
set.add(s.toLowerCase());
return set;
}
I was looking for similar stuff, but was stuck because my ArrayList object was not declared as GENERIC and it was available as raw List type object from somewhere. I was just getting an ArrayList object "_products". So, what I did is mentioned below and it worked for me perfectly ::
List<String> dbProducts = _products;
for(int i = 0; i<dbProducts.size(); i++) {
dbProducts.add(dbProducts.get(i).toLowerCase());
}
That is, I first took my available _products and made a GENERIC list object (As I were getting only strings in same) then I applied the toLowerCase() method on list elements which was not working previously because of non-generic ArrayList object.
And the method toLowerCase() we are using here is of String class.
String java.lang.String.toLowerCase()
not of ArrayList or Object class.
Please correct if m wrong. Newbie in JAVA seeks guidance. :)
Using JAVA 8 parallel stream it becomes faster
List<String> output= new ArrayList<>();
List<String> input= new ArrayList<>();
input.add("A");
input.add("B");
input.add("C");
input.add("D");
input.stream().parallel().map((item) -> item.toLowerCase())
.collect(Collectors.toCollection(() -> output));

For-Each and Pointers in Java [duplicate]

This question already has answers here:
Why does the foreach statement not change the element value?
(6 answers)
Closed 5 years ago.
Ok, so I'm tyring to iterate through an ArrayList and remove a specefic element. However, I am having some trouble using the For-Each like structure. When I run the following code:
ArrayList<String> arr = new ArrayList<String>();
//... fill with some values (doesn't really matter)
for(String t : arr)
{
t = " some other value "; //hoping this would change the actual array
}
for(String t : arr)
{
System.out.println(t); //however, I still get the same array here
}
My question in, how can I make 't' a pointer to 'arr' so that I am able to change the values in a for-each loop? I know I could loop through the ArrayList using a different structure, but this one looks so clean and readable, it would just be nice to be able to make 't' a pointer.
All comments are appreciated! Even if you say I should just suck it up and use a different construct.
I think the best approach may be to use a for loop.
ArrayList<String> arr = new ArrayList<String>();
for (int i = 0; i < arr.size(); i++) {
String t = arr.get(i);
if (// your condition is met) {
arr.set(i, "your new value");
}
}
The problem is that you're trying to change the loop-scoped reference t to let it point to a new String instance. This ain't going to work. It does not refer the actual entry in the arraylist. You need to change the actual value of the reference. If String was mutable and provided a fictive set() method for that, you could in theory do
for (String t : arr) {
t.set("some other value");
}
or so, but that's not possible as it is immutable. Better get a handle of the entrypoint in the array itself using the normal for loop:
for (int i = 0; i < arr.size(); i++) {
arr.set(i, "some other value");
}
If you insist in using the enhanced for loop, then you need to replace String by StringBuilder, which is mutable:
for (StringBuilder t : arr) {
t.delete(0, t.length()).append("some other value");
}
Remember, Java is pass-by-value, not pass-by-reference.
For-each doesn't give you an index pointer, so you just can't use it to change an immutable value.
Either use a for-loop with an index or use a mutable type (like StringBuffer, not String)
An array of objects (like strings) in Java is a contiguous block containing an ordered series of references. So, when you have an array of 4 strings, what you really have is 4 references stored IN the array, and 4 string objects that are outside of the array but are referenced by its 4 elements.
What the for-each construct in Java does is create a local variable and, for each iteration, copy into that local variable the reference from the array cell that corresponds to that iteration. When you set the loop variable (t = " some other value") you are putting a reference to a new string, "some other value", into the local variable t, not into the array.
The contrasts with some other languages (like Perl) where the loop variable acts like an alias to the array/list element itself.
Your code is re-written by the compiler as something like this:
ArrayList<String> arr = new ArrayList<String>();
//... fill with some values (doesn't really matter)
for (final Iterator <String> i = arr.iterator(); i.hasNext();) {
String t;
t = i.next();
t = " some other value "; // just changes where t is pointing
}
To do what you want you would have to write the for loop like this:
for (final ListIterator<String> i = arr.iterator(); i.hasNext();) {
final String t;
t = i.next();
i.set("some other value");
}
Iterator does not have the set method, only ListIterator does.
Basically you want to remove the String t from the list arr. Just do a arr.remove(t) and you could be done. But you can't do it while iterating over the same list. You'll get an Exception if you try to modify the list this way.
You have two options:
clone your list, iterate through the clone and remove the 'specific' String from the original list
create a list for delete candidates, add all 'specific' Strings to that list and, after iterating through the original list, iterate through the wastebin and remove everything you've collected here from the original list.
Option 1 is the easist, the clone can be made like:
List<String> clone = new ArrayList<String>(arr);
You seem to misunderstand how objects/references work in Java, which is pretty fundamental to using the language effectively. However, this code here should do what you want (apologies for the lack of explanation):
ArrayList<String> arr = new ArrayList<String>();
//... fill with some values (doesn't really matter)
for(int i = 0; i < arr.size(); i++)
{
arr.set(i, " some other value "); // change the contents of the array
}
for(String t : arr)
{
System.out.println(t);
}
I believe, this is not related to immutable or mutable.
t = " some other value "; //hoping this would change the actual array
t does not hold the reference to actual object. Java copies the value from arraylist and puts that value into t so array list value does not get affect.
HTH
This has been answered well. Still here is my suggestion. The var t inside loop is only visible there. It will not be seen outside the loop. You could do t.set() if it was not String.
Use a StringBuffer rather than plain strings. This way the string within is mutable.
Strings are immutable. If you had a mutable type like StringBuilder/Buffer, you could change the string in your iteration. You do have references, remember.

Categories

Resources