I want to reverse this:
customArray = myArray;
nameArray = new String[myArray.size()];
for (int i = 0; i < myArray.size(); i++) {
idArray[i] = myArray.get(i).getUnitID();
nameArray[i] = myArray.get(i).getUnitName();
}
if (sortType == SORT)
Arrays.sort(idArray, Collections.reverseOrder());
Arrays.sort(nameArray, ...);
I know how to reverse this by using Arrays.sort(stringArray, Collections.reverseOrder()); but not by index value.
How can I reverse the order of my nameArray based on it's nameArray[i]?.. or even better, since my idArray is actually a list of unique ID's I would like to sort nameArray based on the idArray.
(Update: Now reversing an array of strings and not a list of strings.)
Use Collections.reverse together with Arrays.asList to reverse the array.
Example:
public static void main(String... args) {
String[] array = {"one", "two", "three"};
Collections.reverse(Arrays.asList(array)); // reverses the underlying list
System.out.println(Arrays.toString(array)); // prints [three, two, one]
}
The only solution to your problem is to use an OOP approach. After all, Java is an OOP Language. So instead of having two arrays:
int[] unitID
String[] unitName
which you can't sort in a way that the indexes stay corresponding, write a class Unit that implements Comparable<Unit> and use one array:
Unit[] units
then
Arrays.sort(units);
will do the job.
You would need your own class:
public class Unit implements Comparable<Unit> {
private int id;
private String name;
// Constructor
// Methods
#Override
public int compareTo(Unit other) {
// sorts by id
return this.id - other.id;
// to sort by name, use this:
// return this.name.compareTo(other.name);
}
}
Try this:
import java.util.Collections;
import java.util.List;
import java.util.Arrays;
public void reverseString(String[] stringArray){
List<String> list = Arrays.asList(stringArray);
Collections.reverse(list);
stringArray= (String[]) list.toArray();
}
String[] yourStringArray = new String[]{"Sunday", "Monday", "Tuesday", "Wednesday"};
reverseString(yourStringArray);
//result would be:
//"Wednesday","Tuesday", "Monday", "Sunday"
Related
How to combine three lists:
List<String> one = Arrays.asList("one","four","seven");
List<String> two = Arrays.asList("two","five","eight");
List<String> three = Arrays.asList("three","six");
List<List<String>> merged = ...;
To get in result this:
List {one, two, three, four, five , six , seven, eight}
In real case I need get some queue of matches, from lists (groups) of participants. That in first match play all first participants from different groups. In second match play all second participants and so on. And I will not be able to sort it out.
You can use Java 8 streams to easily merge your lists together and flatMap() it to a single List of String. Sorting by "one", "two", "three" etc. will require a custom sorter because simply sorting by String.compareTo() or any other natural sort will do lexical comparison of characters, not their meanings in English.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Merge {
public static void main(String[] args) {
List<String> one = Arrays.asList("one","four","seven");
List<String> two = Arrays.asList("two","five","eight");
List<String> three = Arrays.asList("three","six");
List<List<String>> merged = Arrays.asList(one, two, three);
System.out.println(merged);
// Output -> [[one, four, seven], [two, five, eight], [three, six]]
List<String> flatMapped = merged.stream().flatMap(List::stream).collect(Collectors.toList());
System.out.println(flatMapped);
// Output -> [one, four, seven, two, five, eight, three, six]
flatMapped.sort((o1, o2) -> {
// TODO - implement sorting logic to return "one", "two", "three", etc.
});
}
}
Two points:
- You cannot sort number words, written in Strings by the number. Therefore you have to do some mapping, e.g. with a Map, which is then sort by keys or you write a Comparator for the sort method
- Arrays.asList(...) generates a unmodifiable list, you cannot add something to it
So, this works for me:
List<String> one = new ArrayList<>(Arrays.asList("one", "four", "seven"));
List<String> two = new ArrayList<>(Arrays.asList("two", "five", "eight"));
List<String> three = new ArrayList<>(Arrays.asList("three", "six", "ten"));
one.addAll(two);
one.addAll(three);
one.sort((o1, o2) -> {
// Declare here, which value is less, equal or greater than the other
return 0;
});
By default, when you sort a list of String's, they will be sorted in lexicographic order (a-z, 0-9, etc.), and thus you cannot expect Collections.sort to sort your list of String's in the order that you expect.
Thus you will need to implement a custom Comparator that can do what want, and use the method signature Collections.sort(list, yourCustomComparator).
If you want just to combine the lists without altering their order, then you can do something like:
public static void main(String[] args) {
List<String> one = Arrays.asList("one","four","seven");
List<String> two = Arrays.asList("two","five","eight");
List<String> three = Arrays.asList("three","six");
System.out.println(zipLists(one, two, three));
//[one, two, three, four, five, six, seven, eight]
}
public static List<String> zipLists(List<String>... lists) {
int maxSize = 0, totalSize = 0;
List<Iterator<String>> iterators = new ArrayList<>(lists.length);
for(List<String> list: lists) {
int size = list.size();
maxSize = Math.max(maxSize, size);
totalSize += size;
iterators.add(list.iterator());
}
List<String> mergedList = new ArrayList<>(totalSize);
for(int i = 0; i < maxSize; i++) {
for(Iterator<String> iterator: iterators) {
if(iterator.hasNext()) {
mergedList.add(iterator.next());
}
}
}
return mergedList;
}
Assuming all you want to do is take elements from the source lists one at a time and 'weave' them in with the other lists...
Recursive solution:
public static List<String> MergeLists (List<List<String>> a2 ) {
List<String> h = new ArrayList<String>();
List<List<String>> a = new ArrayList<List<String>>();
boolean call = false;
for (List<String> l : a2) {
if (! l.isEmpty()) {
h.add(l.get(0));
if (l.size() > 0) {
a.add((List<String>) l.subList(1, l.size()));
call = true;
}
}
}
if (call) { h.addAll(MergeLists(a)); return h;}
else return h;
}
Hello everyone I have a code using an arraylist, these are the test inputs to be added. But after I use the sort method. The output is not the one I expected.
ArrayList<String> test= new ArrayList<>();
test.add("2,2,17");
test.add("5,4,24 ");
test.add("8,1,11");
test.add("19,0,0");
test.add("2,3,21");
test.sort(null);
Output :
19,0,0
2,2,17
2,3,21
5,4,24
8,1,11
My desired out put should be :
2,2,17
2,3,21
5,4,24
8,1,11
19,0,0
Is there a way to sort "19,0,0" to be at the end, or any number to be add to make it the end of the arrayList?
You'll want to use Collections.sort, something like this:
Collections.sort(list, new Comparator<String>() {
#Override
public int compare(String s1, String s2) {
int s1int = Integer.parseInt(s1.substring(0, s1.indexOf(",")));
int s2int = Integer.parseInt(s2.substring(0, s2.indexOf(",")));
return s1int - s2int;
}
});
You can use Collections.sort()
https://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#sort(java.util.List,%20java.util.Comparator).
And define a Comparator to compare the objects in the list.
In order for the strings to be sorted alphabetically rather than numerically, you will need to implement a comparator that converts the strings to integers for the comparison. You can then use this comparator with Collections.sort() to sort your list.
A better option would be to store your integers as integers in a 2D array rather than as strings (or some kind of nested list if the dimensions are not known up-front); however, I'd need to know more about how the data is created and used before uniformly proclaiming this to e the solution.
A possible flexible solution for Strings of various 'lengths', i.e. a different number of integers separated by commas.
Example list
2,2,17
5,4,24
19,0,2
8,1,11
19,0,1,2
19,0,1,4
2,3,21
2
Result after sorting
2
2,2,17
2,3,21
5,4,24
8,1,11
19,0,1,2
19,0,1,4
19,0,2
Code
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class SortExample {
public static void main(String[] args) {
List<String> test = new ArrayList<>();
test.add("2,2,17");
test.add("5,4,24");
test.add("19,0,2");
test.add("8,1,11");
test.add("19,0,1,2");
test.add("19,0,1,4");
test.add("2,3,21");
test.add("2");
Collections.sort(test, new Comparator<String>() {
#Override
public int compare(String s1, String s2) {
String[] split1 = s1.split(",");
String[] split2 = s2.split(",");
final int indicesToCheck = Math.min(split1.length, split2.length);
int result = 0;
int i = 0;
while (result == 0 && i < indicesToCheck) {
result = Integer.compare(Integer.parseInt(split1[i]),
Integer.parseInt(split2[i]));
i++;
}
return result == 0 ? Integer.compare(split1.length, split2.length) : result;
}
});
for (String s : test) {
System.out.println(s);
}
}
}
This question already has answers here:
Storing arrays in Set and avoiding duplicates
(6 answers)
Closed 9 years ago.
I have set of string array and i want to remove duplicate elements from this...
String[] arr1 = {"a1","b1"};
String[] arr2 = {"a2","b2"};
Set<String[]> mySet = new HashSet<String[]>();
mySet.add(arr1);
mySet.add(arr2);
mySet.add(new String[] {"a1","b1"});
System.out.print(mySet.size());
Currently mySet looks like this:
[{"a1","b1"},{"a2","b2"},{"a1","b1"}]
But I want like this:
[{"a1","b1"},{"a2","b2"}]
I know some ways...
Every time I need to run inner loop and check whether its duplicate or not.
Can I override the set's behavior? (hashcode or equals)? ( i do not know how....)
Do I need to change data structure for this? (linkedhashset or list or any other suitable data structure for this?)
Arrays inherit from Object and don't override the hashCode and equals methods. A HashSet uses a Map implementation, which in turn, uses hashCode and equals to avoid duplicate elements.
You can use a TreeSet with a custom Comparator that compares the String arrays for equality.
Set<String[]> mySet = new TreeSet<>(new Comparator<String[]>() {
#Override
public int compare(String[] o1, String[] o2) {
return Arrays.equals(o1, o2)? 0 : Arrays.hashCode(o1) - Arrays.hashCode(o2);
}
});
Note that this will only neglect duplicate arrays with the same corresponding elements. If the order of elements is different, it won't be considered as a duplicate.
If you want to be able to discard unordered duplicates, for e.g., {a1, b1} and {b1, a1}, use this:
#Override
public int compare(String[] o1, String[] o2) {
int comparedHash = o1.hashCode() - o2.hashCode();
if(o1.length != o2.length) return comparedHash;
List<String> list = Arrays.asList(o1);
for(String s : o2) {
if(!list.contains(s)) return comparedHash;
}
return 0;
}
The array hashcode is independent of the contents of the array (it inherits the Object hashcode, which uses the array's reference).
However, List would do what you want. It uses a hashcode based on the elements in the List . From Java Docs:
int hashCode = 1;
for (E e : list)
hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
Example:
List<String> list1 = Arrays.asList("a1","b1");
List<String> list2 = Arrays.asList("a2","b2");
Set<List<String>> mySet = new HashSet<List<String>>();
mySet.add(list1);
mySet.add(list2);
mySet.add(Arrays.asList("a1","b1")); // duplicate won't be added
System.out.print(mySet.size()); // size = 2
Arrays uses identity-based Object.hashCode() implementation and there is no easy way to check if they are equal. If it all you still want to go ahead with your problem I would suggest you to use TreeSet with Comparator
Though not fail proof approach, but you should be able to build fine tuned solution out of my example,
public static void main(String[] args) {
String[] arr1 = {"a1","b1"};
String[] arr2 = {"a2","b2"};
Set<String[]> mySet = new TreeSet<String[]>(new ArrayComparator());
mySet.add(arr1);
mySet.add(arr2);
mySet.add(new String[] {"a1","b1"});
System.out.println(mySet.size());
for(String[] aa: mySet){
System.out.println(aa[0]+" , "+aa[1]);
}
}
}
class ArrayComparator implements Comparator {
#Override
public int compare(Object o1, Object o2) {
String[] ar1 =(String[]) o1;
String[] ar2 =(String[]) o2;
if(ar1.length!=ar2.length){
return -1;
}
for(int count=0;count<ar1.length;count++){
if(!ar1[count].equals(ar2[count])){
return -1;
}
}
return 0;
}
Why not use a List implementation? The list.equals will compare elements in each list and determine equality.
List<String> arr1 = new ArrayList<String>();
arr1.add("a1");
arr1.add("b1");
List<String> arr2 = new ArrayList<String>();
arr2.add("a2");
arr2.add("b2");
Set<List<String>> mySet = new HashSet<List<String>>();
mySet.add(arr1);
mySet.add(arr2);
List<String> arr3 = new ArrayList<String>();
arr3.add("a1");
arr3.add("b1");
mySet.add(arr3);
System.out.print(mySet.size());
You suggest overriding equals and hashcode methods. HashSet is backed by a hashmap that uses the hashcode function as its key. So actually you need to override hashcode to represent your equals criteria.
One problem with this. I believe String and therefore String [] are declared as final, so you can't extend them :(
instead of taking array of string you can create a class Like this..
public class String1 implements Comparable<String1>{
String str1;
String str2;
public String1(String a, String b) {
str1 = a;
str2 = b;
}
public String getStr1() {
return str1;
}
}
public String getStr2() {
return str2;
}
#Override
public String toString() {
return "String1 [str1=" + str1 + ", str2=" + str2
+ "]";
}
#Override
public int compareTo(String1 o) {
if(str1.contentEquals(o.getStr1()) && str2.contentEquals(o.getStr2())) return 0 ;
return 1;
}
}
And after that insteed of string you can take this one class object.
replace HashSet with TreeSet. Like this .
String1 arr1 =new String1("a1","b1");
String1 arr2 =new String1("a2","b2");
Set<String1> mySet = new TreeSet<String1>();
mySet.add(arr1);
mySet.add(arr2);
mySet.add(new String1("a1","b1"));
System.out.print(mySet.size());
System.out.println(mySet.toString());
So this will sort as well this will check for duplicate also.
try to this code.............
import java.util.HashSet;
import java.util.Set;
public class setDemo {
static Set<String[]> mySet = new HashSet<String[]>();
static Set tempSet = new HashSet();
public static void main(String[] args) {
String[] arr1 = {"a1","b1"};
String[] arr2 = {"a2","b2"};
addObject(arr1);
addObject(arr2);
addObject(new String[] {"a1","b1"});
System.out.print(mySet.size());
// System.out.println(tempSet);
}
public static void addObject(String[] o){
StringBuffer sb = new StringBuffer();
for(Object obj:o){
sb.append(obj.toString());
}
if(!tempSet.contains(sb.toString())){
tempSet.add(sb.toString());
mySet.add(o);
}
}
}
Try something like this...
public static void main(String... args) {
String[] arr1 = {"a1","b1"};
String[] arr2 = {"a2","b2"};
Set<String[]> mySet = new HashSet<String[]>();
mySet.add(arr1);
mySet.add(arr2);
String str[] =new String[] {"a1","b1"};
long t1 = System.nanoTime();
boolean b =checkContains(str,mySet);
long t2=System.nanoTime();
long t = t2-t1;
System.out.println("time taken : " + t );
System.out.println(b);
if(!b)
{
mySet.add(str);
}
}
public static boolean checkContains(String[] str, Set mySet)
{
Iterator it = mySet.iterator();
while(it.hasNext())
{
String[] arr = (String[])it.next();
if(arr[0].equals(str[0]) && arr[1].equals(str[1]) )
{
return true;
}
}
return false;
}
OP :
time taken : 184306
true
Here instead of keeping Set you can use Set<SomeClass> and the override the hash and equals method for the class SomeClass so it will solve your problem.
at my work I've got the following source code:
import java.util.ArrayList;
import java.util.List;
public class Temporaer
{
public static void main(String[] args)
{
List stringArrayList = new java.util.ArrayList();
stringArrayList.add(fillStringArrayElement("a", "b"));
stringArrayList.add(fillStringArrayElement("c", "d"));
String[] listElement;
/*
* I'm stuck here, because I don't know what I have to do
*/
System.out.println(listElement.length);
}
//Just a method to fill a list easily
private static String[] fillStringArrayElement (String firstElem, String secondElem)
{
String[] stringArrayListElement = new String[2];
stringArrayListElement[0] = firstElem;
stringArrayListElement[1] = secondElem;
return stringArrayListElement;
}
}
My goal is it to extract each list item and work with those.
I tried to use the toArray[T[]) method as mentioned here. Though it generates an java.lang.ArrayStoreException. Note: I cannot change the type of the list because the list is filled by an extern service. Maybe I have to convert the list first...
Can someone show me a way to achive my goal? Thanks in advanced.
Iterator is an interface in java used to iterate over a Collection like ArrayList or other Collection framework classes.
Before reading ArrayList make sure values are available using the size() method.
Here a sample working snippet for your problem.
String [] myArray ;
if (stringArrayList.size()>0){
Iterator<String [] > i = stringArrayList.iterator();
while(i.hasNext()){
myArray = i.next();
for(String s : myArray)
System.out.println(s);
}
}
}
Don't use Raw ArrayList, instead use Generics
Use this:
List<String[]> stringArrayList = new java.util.ArrayList<String[]>();
stringArrayList.add(new String[]{"a", "b"});
stringArrayList.add(new String[]{"c", "d"});
//if you cant to convert the stringArrayList to an array:
String[][] listElement = stringArrayList.toArray(new String[0][]);
for (String[] inArr : listElement){
for (String e : inArr){
System.out.print(e + " ");
}
System.out.println();
}
String[] listElement;
Above statements is incorrect because you are keeping arrays in list so your listElement must contain String[] .
String [][] listElement
Something like below.
listElement=stringArrayList.toArray(new String[stringArrayList.size()][]);
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to create ArrayList (ArrayList<T>) from array (T[]) in Java
How to implement this method:
List<Integer> toList(int[] integers) {
???
//return Arrays.asList(integers); doesn't work
}
There's probably a built-in method to do it somewhere* (as you note, Arrays.asList won't work as it expects an Integer[] rather than an int[]).
I don't know the Java libraries well enough to tell you where that is. But writing your own is quite simple:
public static List<Integer> createList(int[] array) {
List<Integer> list = new ArrayList<Integer>(array.length);
for (int i = 0; i < array.length; ++i) {
list.add(array[i]);
}
return list;
}
Obviously one downside of this is that you can't do it generically. You'll have to write a separate createList method for each autoboxed primitive type you want.
*And if there isn't, I really wonder why not.
Use commons-lang3 org.apache.commons.lang3.ArrayUtils.toObject(<yout int array>) and then java.util.Arrays.asList(<>)
ArrayUtils.toObject() will copy the array, and Array.asList() will simply create list that is backed by new array.
int[] a = {1, 2, 3};
List<Integer> aI = Arrays.asList(ArrayUtils.toObject(a));
EDIT: This wont work if you want to add() new elements (resize) though the list interface, if you want to be able to add new elements, you can use new ArrayList(), but this will create one more copy.
List<Integer> asList(final int[] integers) {
return new AbstractList<Integer>() {
public Integer get(int index) {
return integers[index];
}
public int size() {
return integers.length;
}
};
}
List<Integer> toList(int[] integers) {
// Initialize result's size to length of the incoming array
// this way it will not require reallocations
ArrayList<Integer> result = new ArrayList<Integer>( integers.length );
for ( int cur: integers )
{
result.add( Integer.valueOf( cur ) );
}
return result;
}
I do not think there is a quick way to do it unfortunately. I believe you will have to iterate the array and add it one by one.
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
public class Listing {
public static void main(String[] args) {
int[] integers = {1,2,3,4};
java.util.List<Integer> list = new ArrayList<Integer>();
for (int i=0; i< integers.length; i++)
{
list.add(integers[i]);
}
System.out.println(list);
}
}
Tested and working as expected!