Hello I would like to make a custom method for ArrayList class.
So lets say I make a new ArrayList.
ArrayList<String> list = new ArrayList<String>
I would like to make a method I can call on list.
Something like this:
list.myMethod();
What I want to solve with my method is so you can get an Object by Object name and not index inside the ArrayList.
So basically I want to make a method returning following:
list.get(list.indexOf(str));
To sum it up:
ArrayList<String> list= new ArrayList<>();
String str = "asd";
String str2 = "zxc";
list.add(str2);
list.add(str);
System.out.println(list.get(0));
System.out.println(list.get(list.indexOf(str)));
Will print: "asd" "asd".
So instead of writing: list.get(list.indexOf(Object))
I would like to be a able to write list.myMethod(Object) and get the same result. I hope you understand my question. I know this is probably a dumb solution and I could just use a Map. But this is for learning purpose only and nothing I will use.
Custom method >>
public class MyArrayList<E> extends ArrayList<E> {
public E getLastItem(){
return get(size()-1);
}
}
How to use it >>
MyArrayList<String> list= new MyArrayList<>();
String str = "asd";
String str2 = "zxc";
list.add(str2);
list.add(str);
System.out.println(list.getLastItem());
what you need requires to extend the ArrayList classs, but you should consider using instead a
Map<String, Object>
with that approach you can do something like
myMap.get("myObject1");
You should just extend the ArrayList class creating your own with the new method. But the performance would be horrible if your list grow too much. The indexOf method have O(n), so greater is the size of your array longer is the time you have to wait.
May be you should choose a different collection if you want access directly to the element. In your case, it elements stored in the collection are unique, you could use a Set.
On the other hand, a Set does not preserve the insertion order. I don't know if this is a think you have to care of.
And a Set just let you know if the element is contained into the collection.
Another collection that can be of your interest is the Map, this is a key-value collection.
But given that you have only keys this it seems not be your case.
So I am currently having a problem understanding how to access a set, is that even allowed? So I understand my set of names contains a set of Character objects. I also understand that my toString() method call converts these Character objects into a String, but not a conventional string -- which is why I have [s,a] rather than [sa]. So my question is, is if there is a way to make me have a list of individual strings. So I want my list to be = [s, a] rather than [ [s,a] ]. Is this even possible? I apologize if this makes no sense; nevertheless, if you do understand my fumbled explanation thank you for your time and help. If you need for me to explain more, I will.
//this all works
Set<Character> names = find(prefix).getRollCall().keySet();
//[s,a]
String lists = names.toString();
//[s,a]
List<String> sloop = Arrays.asList(lists);
//[[s,a]]
If you want to convert a Set<Character> to a List<Character> you can do
List<Character> list = new ArrayList<Character>(set);
If you want to convert a Set<Character> to a List<String> you can do
List<String> list = new ArrayList<String>();
for (char c : set)
list.add("" + c);
Don't use toString() at all. Iterate over the elements of the Set and build up whatever string you like.
Set<Character> names = find(prefix).getRollCall().keySet();
for (Character c : names)
{
// whatever you like
}
Let me explain what's happening in your code, in case you aren't clear:
String lists = names.toString();
This calls the standard toString method for a collection which converts your set to an ordinary (conventional) string in a standard format (i.e. comma delimited, in brackets). There's nothing special about the string that is created: "[s, a]".
List<String> sloop = Arrays.asList(lists);
The asList method takes one or more arguments and converts them into a list. Because you've given it only a single argument lists it creates a list with a single string element: ("[s, a]")
Then, later, I suspect you are doing something like:
System.out.println(sloop);
This again calls the standard toString method for a collection (in this case the List sloop) and again creates a comma delimited, bracket enclosed standard string: "[[s, a]]"
So, most of that is probably not what you want. Your lists variable isn't a List, it's a String which I assume isn't what you want.
If you are just looking to convert your set of character to a list of strings, then this is pretty trivial in Java 8:
List<String> lists = names.stream().map(Character::toString).collect(Collectors.toList());
I need to get a String[] out of a Set<String>, but I don't know how to do it. The following fails:
Map<String, ?> myMap = gpxlist.getAll();
Set<String> myset = myMap.keySet();
String[] GPXFILES1 = (String[]) myset.toArray(); // Here it fails.
How can I fix it so that it works?
Use the Set#toArray(IntFunction<T[]>) method taking an IntFunction as generator.
String[] GPXFILES1 = myset.toArray(String[]::new);
If you're not on Java 11 yet, then use the Set#toArray(T[]) method taking a typed array argument of the same size.
String[] GPXFILES1 = myset.toArray(new String[myset.size()]);
While still not on Java 11, and you can't guarantee that myset is unmodifiable at the moment of conversion to array, then better specify an empty typed array.
String[] GPXFILES1 = myset.toArray(new String[0]);
Java 11
The new default toArray method in Collection interface allows the elements of the collection to be transferred to a newly created array of the desired runtime type. It takes IntFunction<T[]> generator as argument and can be used as:
String[] array = set.toArray(String[]::new);
There is already a similar method Collection.toArray(T[]) and this addition means we no longer be able to pass null as argument because in that case reference to the method would be ambiguous. But it is still okay since both methods throw a NPE anyways.
Java 8
In Java 8 we can use streams API:
String[] array = set.stream().toArray(String[]::new);
We can also make use of the overloaded version of toArray() which takes IntFunction<A[]> generator as:
String[] array = set.stream().toArray(n -> new String[n]);
The purpose of the generator function here is to take an integer (size of desired array) and produce an array of desired size. I personally prefer the former approach using method reference than the later one using lambda expression.
Use toArray(T[] a) method:
String[] array = set.toArray(new String[0]);
Guava style:
Set<String> myset = myMap.keySet();
FluentIterable.from(mySet).toArray(String.class);
more info: https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/FluentIterable.html
In Java 11 we can use Collection.toArray(generator) method. The following code will create a new array of String:
Set<String> set = Set.of("one", "two", "three");
String[] array = set.toArray(String[]::new)
See: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Collection.html#toArray(java.util.function.IntFunction)
Set<String> stringSet= new HashSet<>();
String[] s = (String[])stringSet.toArray();
I was facing the same situation.
I begin by declaring the structures I need:
Set<String> myKeysInSet = null;
String[] myArrayOfString = null;
In my case, I have a JSON object and I need all the keys in this JSON to be stored in an array of strings. Using the GSON library, I use JSON.keySet() to get the keys and move to my Set :
myKeysInSet = json_any.keySet();
With this, I have a Set structure with all the keys, as I needed it. So I just need to the values to my Array of Strings. See the code below:
myArrayOfString = myKeysInSet.toArray(new String[myKeysInSet.size()]);
This was my first answer in StackOverflow.
Sorry for any error :D
I have text file with list of alphabets and numbers. I want to do sorting w.r.t this number using java.
My text file looks like this:
a--->12347
g--->65784
r--->675
I read the text file and i split it now. But i dont know how to perform sorting . I am new to java. Please give me a idea.
My output want to be
g--->65784
a--->12347
r--->675
Please help me. Thanks in advance.
My coding is
String str = "";
BufferedReader br = new BufferedReader(new FileReader("counts.txt"));
while ((str = br.readLine()) != null) {
String[] get = str.split("---->>");
When i search the internet all suggest in the type of arrays. I tried. But no use.How to include the get[1] into array.
int arr[]=new int[50]
arr[i]=get[1];
for(int i=0;i<50000;i++){
for(int j=i+1;j<60000;j++){
if(arr[i]>arr[j]){
System.out.println(arr[i]);
}
}
You should use the Arrays.sort() or Collections.sort() methods that allows you to specify a custom Comparator, and implement such a Comparator to determine how the strings should be compared for the purpose of sorting (since you don't want the default lexicographic order). It looks like that should involve parsing them as integers.
Your str.split looks good to me. Use Integer.parseInt to get an int out of the string portion representing the number. Then put the "labels" and numbers in a TreeMap as described below. The TreeMap will keep the entries sorted according to the keys (the numbers in your case).
import java.util.TreeMap;
public class Test {
public static void main(String[] args) {
TreeMap<Integer, String> tm = new TreeMap<Integer, String>();
tm.put(12347, "a");
tm.put(65784, "g");
tm.put(675, "r");
for (Integer num : tm.keySet())
System.out.println(tm.get(num) + "--->" + num);
}
}
Output:
r--->675
a--->12347
g--->65784
From the API for TreeMap:
The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.
you can use TreeMap and print its content with iterator for keys. You may have to implement your own Comparator.
rather than give you the code, I would point you on the following path: TreeMap. Read, learn, implement
What you want to do is:
1) convert the numbers into integers
2) Store them in a collection
3) use Collections.sort() to sort the list.
I assume that you are an absolute beginner.
You are correct till the split part.
You need to place the split number immediately into a string or object (custom object)
You would create something like:
class MyClass //please, a better name,
{
//and better field names, based on your functionality
int number;
String string;
}
Note: You have to implement equals and hashCode
After the split (your first snippet), create an object of this class, place get[0] into string and get[1] into number (after converting the string to integer)
You place this object into an TreeMap.
Now you have a sorted list.
I have deliberately not specified the details. Feel free to google for any term/phrase you dont understand. By this way you understand, rather than copy pasting some code.
I have a list of integers, List<Integer> and I'd like to convert all the integer objects into Strings, thus finishing up with a new List<String>.
Naturally, I could create a new List<String> and loop through the list calling String.valueOf() for each integer, but I was wondering if there was a better (read: more automatic) way of doing it?
Using Google Collections from Guava-Project, you could use the transform method in the Lists class
import com.google.common.collect.Lists;
import com.google.common.base.Functions
List<Integer> integers = Arrays.asList(1, 2, 3, 4);
List<String> strings = Lists.transform(integers, Functions.toStringFunction());
The List returned by transform is a view on the backing list - the transformation will be applied on each access to the transformed list.
Be aware that Functions.toStringFunction() will throw a NullPointerException when applied to null, so only use it if you are sure your list will not contain null.
Solution for Java 8. A bit longer than the Guava one, but at least you don't have to install a library.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
//...
List<Integer> integers = Arrays.asList(1, 2, 3, 4);
List<String> strings = integers.stream().map(Object::toString)
.collect(Collectors.toList());
For Java 11,
List<String> strings = integers.stream().map(Object::toString)
.collect(Collectors.toUnmodifiableList());
Still no map convenience method, really?
As far as I know, iterate and instantiate is the only way to do this. Something like (for others potential help, since I'm sure you know how to do this):
List<Integer> oldList = ...
/* Specify the size of the list up front to prevent resizing. */
List<String> newList = new ArrayList<>(oldList.size());
for (Integer myInt : oldList) {
newList.add(String.valueOf(myInt));
}
What you're doing is fine, but if you feel the need to 'Java-it-up' you could use a Transformer and the collect method from Apache Commons, e.g.:
public class IntegerToStringTransformer implements Transformer<Integer, String> {
public String transform(final Integer i) {
return (i == null ? null : i.toString());
}
}
..and then..
CollectionUtils.collect(
collectionOfIntegers,
new IntegerToStringTransformer(),
newCollectionOfStrings);
The source for String.valueOf shows this:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
Not that it matters much, but I would use toString.
Instead of using String.valueOf I'd use .toString(); it avoids some of the auto boxing described by #johnathan.holland
The javadoc says that valueOf returns the same thing as Integer.toString().
List<Integer> oldList = ...
List<String> newList = new ArrayList<String>(oldList.size());
for (Integer myInt : oldList) {
newList.add(myInt.toString());
}
Here's a one-liner solution without cheating with a non-JDK library.
List<String> strings = Arrays.asList(list.toString().replaceAll("\\[(.*)\\]", "$1").split(", "));
Another Solution using Guava and Java 8
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<String> strings = Lists.transform(numbers, number -> String.valueOf(number));
To the people concerned about "boxing" in jsight's answer: there is none. String.valueOf(Object) is used here, and no unboxing to int is ever performed.
Whether you use Integer.toString() or String.valueOf(Object) depends on how you want to handle possible nulls. Do you want to throw an exception (probably), or have "null" Strings in your list (maybe). If the former, do you want to throw a NullPointerException or some other type?
Also, one small flaw in jsight's response: List is an interface, you can't use the new operator on it. I would probably use a java.util.ArrayList in this case, especially since we know up front how long the list is likely to be.
List<String> stringList = integerList.stream().map((Object s)->String.valueOf(s)).collect(Collectors.toList())
Not core Java, and not generic-ified, but the popular Jakarta commons collections library has some useful abstractions for this sort of task. Specifically, have a look at the collect methods on
CollectionUtils
Something to consider if you are already using commons collections in your project.
A slightly more concise solution using the forEach method on the original list:
List<Integer> oldList = Arrays.asList(1, 2, 3, 4, 5);
List<String> newList = new ArrayList<>(oldList.size());
oldList.forEach(e -> newList.add(String.valueOf(e)));
#Jonathan: I could be mistaken, but I believe that String.valueOf() in this case will call the String.valueOf(Object) function rather than getting boxed to String.valueOf(int). String.valueOf(Object) just returns "null" if it is null or calls Object.toString() if non-null, which shouldn't involve boxing (although obviously instantiating new string objects is involved).
I think using Object.toString() for any purpose other than debugging is probably a really bad idea, even though in this case the two are functionally equivalent (assuming the list has no nulls). Developers are free to change the behavior of any toString() method without any warning, including the toString() methods of any classes in the standard library.
Don't even worry about the performance problems caused by the boxing/unboxing process. If performance is critical, just use an array. If it's really critical, don't use Java. Trying to outsmart the JVM will only lead to heartache.
An answer for experts only:
List<Integer> ints = ...;
String all = new ArrayList<Integer>(ints).toString();
String[] split = all.substring(1, all.length()-1).split(", ");
List<String> strs = Arrays.asList(split);
Lambdaj allows to do that in a very simple and readable way. For example, supposing you have a list of Integer and you want to convert them in the corresponding String representation you could write something like that;
List<Integer> ints = asList(1, 2, 3, 4);
Iterator<String> stringIterator = convertIterator(ints, new Converter<Integer, String> {
public String convert(Integer i) { return Integer.toString(i); }
}
Lambdaj applies the conversion function only while you're iterating on the result.
You can't avoid the "boxing overhead"; Java's faux generic containers can only store Objects, so your ints must be boxed into Integers. In principle it could avoid the downcast from Object to Integer (since it's pointless, because Object is good enough for both String.valueOf and Object.toString) but I don't know if the compiler is smart enough to do that. The conversion from String to Object should be more or less a no-op, so I would be disinclined to worry about that one.
Just for fun, a solution using the jsr166y fork-join framework that should in JDK7.
import java.util.concurrent.forkjoin.*;
private final ForkJoinExecutor executor = new ForkJoinPool();
...
List<Integer> ints = ...;
List<String> strs =
ParallelArray.create(ints.size(), Integer.class, executor)
.withMapping(new Ops.Op<Integer,String>() { public String op(Integer i) {
return String.valueOf(i);
}})
.all()
.asList();
(Disclaimer: Not compiled. Spec is not finalised. Etc.)
Unlikely to be in JDK7 is a bit of type inference and syntactical sugar to make that withMapping call less verbose:
.withMapping(#(Integer i) String.valueOf(i))
This is such a basic thing to do I wouldn't use an external library (it will cause a dependency in your project that you probably don't need).
We have a class of static methods specifically crafted to do these sort of jobs. Because the code for this is so simple we let Hotspot do the optimization for us. This seems to be a theme in my code recently: write very simple (straightforward) code and let Hotspot do its magic. We rarely have performance issues around code like this - when a new VM version comes along you get all the extra speed benefits etc.
As much as I love Jakarta collections, they don't support Generics and use 1.4 as the LCD. I am wary of Google Collections because they are listed as Alpha support level!
I didn't see any solution which is following the principal of space
complexity. If list of integers has large number of elements then it's
big problem.
It will be really good to remove the integer from the List<Integer> and free
the space, once it's added to List<String>.
We can use iterator to achieve the same.
List<Integer> oldList = new ArrayList<>();
oldList.add(12);
oldList.add(14);
.......
.......
List<String> newList = new ArrayList<String>(oldList.size());
Iterator<Integer> itr = oldList.iterator();
while(itr.hasNext()){
newList.add(itr.next().toString());
itr.remove();
}
I just wanted to chime in with an object oriented solution to the problem.
If you model domain objects, then the solution is in the domain objects. The domain here is a List of integers for which we want string values.
The easiest way would be to not convert the list at all.
That being said, in order to convert without converting, change the original list of Integer to List of Value, where Value looks something like this...
class Value {
Integer value;
public Integer getInt()
{
return value;
}
public String getString()
{
return String.valueOf(value);
}
}
This will be faster and take up less memory than copying the List.