Compare all values of arraylist to a string - java

I have an array list abc which has certain values -
ArrayList< String > abc = new ArrayList<>();
abc.add("hi");
abc.add("hello Yash");
abc.add("i am Yash");
String x = "Yash";
Now, I want to know if x is contained in any of the elements of abc.
If it is, then get the index of the elements which contain x.

Here is a simple solution:
public class FindText
{
public static void main(String[] args)
{
ArrayList< String > abc = new ArrayList<>();
abc.add("hi");
abc.add("hello Yash");
abc.add("i am Yash");
String x = "Yash";
for(int i=0; i<abc.size(); i++)
{
if(abc.get(i).contains(x))
{
int index = i;
System.out.println(index);
}
}
}
}
It gives you 1 and 2 as indexes which includes the text "Yash"

You can achieve this in 2 different ways...
The old school
and the lambdas way
Old school Example:
public static void main(String[] args) {
List<String> abc = new ArrayList<>();
abc.add("hi");
abc.add("hello Yash");
abc.add("i am Yash");
String x = "Yash";
List<String> resultOldSchool = new ArrayList<>();
for (String sentence : abc) {
if (sentence.contains(x)) {
resultOldSchool.add(sentence);
}
}
System.out.println(resultOldSchool);
}
Lambdas way Example:
public static void main(String[] args) {
List<String> abc = new ArrayList<>();
abc.add("hi");
abc.add("hello Yash");
abc.add("i am Yash");
String x = "Yash";
List<String> resultJava8 = findStringInList(abc, x);
if (!resultJava8.isEmpty()) {
System.out.println(resultJava8);
}
}
public static List<String> findStringInList(final List<String> list, final String strng) {
return list.stream().filter(s -> s.contains(strng)).collect(Collectors.toList());
}
feel free to decide....

Assuming that abc is a List<String> and x is a String then this should do the trick.
List<Integer> indexes = new LinkedList<Integer>();
for(int i = 0; i < abc.size(); i++)
{
if(abc.get(i).contains(x))
indexes.add(i);
}
After the loop finishes all the indexes of the elements that contain x will be in the indexes list.

Related

Efficient way to merge map with another map on partial matches of a field

Say I have the following classes:
class PersonWithFirstName {
String firstName;
}
class PersonWithFullName {
String fullName; // note assume this is not delimited in any way
}
class PersonWithFirstNameAndFullName {
String firstName;
List fullNames;
}
Now given a Map<Integer, PersonWithFirstName> and a Map<Integer, PersonWithFullName> where the key is the id (but the ids from the two maps are not coorelated), I want to write a function that returns PersonWithFirstNameAndFullName which for each firstName in Map<String, PersonWithFirstName>, finds any full names in the other map that begin with this firstName.
As an example:
Map<Integer, PersonWithFirstName> mapPersonsWithFirstName = new HashMap<>();
Map<Integer, PersonWithFulltName> mapPersonsWithFullName = new HashMap<>();
mapPersonsWithFirstName.set(1, new PersonWithFirstName("bob"));
mapPersonsWithFirstName.set(2, new PersonWithFirstName("alice"));
mapPersonsWithFullName.set(1, new PersonWithFullName("bobjohnson"));
mapPersonsWithFullName.set(2, new PersonWithFullName("bobjames"));
myFunction(mapPersonsWithFirstName, mapPersonsWithFullName)
/* should return
{
1: {
firstName: "bob"
fullNames: ["bobjohnson", "bobjames"]
},
2: {
firstName: "alice"
fullNames: []
}
}
*/
The only way I came up with is looping through the entryset of mapPersonsWithFirstName, and for each PersonWithFirstName doing another loop through mapPersonsWithFullName to find any PersonWithFullName.fullName that starts with PersonWithFirstName.firstName. This runs is exponential time, but I'm really thinking this can be solved in linear time. Any help is appreciated!
You could use TreeSet for ordering all your names and then just get desired subsequences (using tailSet and headSet methods):
private static List<PersonWithFirstNameAndFullName> myFunction(List<String> firstNames, List<String> fullNames) {
List<PersonWithFirstNameAndFullName> res = new ArrayList<>();
firstNames.sort(Comparator.reverseOrder());
NavigableSet<String> allNames = Stream.concat(firstNames.stream(), fullNames.stream()).collect(Collectors.toCollection(TreeSet::new));
for (String firstName : firstNames) {
final SortedSet<String> tail = allNames.tailSet(firstName, false);
allNames = new TreeSet<>(allNames.headSet(firstName));
res.add(new PersonWithFirstNameAndFullName(firstName, new ArrayList<>(tail)));
}
return res;
}
If the code above doesn't quite meet your requirements, you can change it.
But, in general, the main idea is to use TreeSet or TreeMap.
Update (to match the signature of your methods):
public static List<PersonWithFirstNameAndFullName> myFunction(Map<Integer, PersonWithFirstName> mapPersonsWithFirstName, Map<Integer, PersonWithFullName> mapPersonsWithFullName) {
return myFunction(mapPersonsWithFirstName.values().stream().map(PersonWithFirstName::getFirstName).collect(Collectors.toList()),
mapPersonsWithFullName.values().stream().map(PersonWithFullName::getFullName).collect(Collectors.toList()));
}
I think this way It is not exponential anymore:
public static void main(String[] args) {
Map<Integer, PersonWithFirstName> firstNames = new HashMap<>();
Map<Integer, PersonWithFullName> fullNames = new HashMap<>();
firstNames.put(1, new PersonWithFirstName("bob"));
firstNames.put(2, new PersonWithFirstName("alice"));
firstNames.put(3, new PersonWithFirstName("test1"));
firstNames.put(4, new PersonWithFirstName("test2"));
firstNames.put(5, new PersonWithFirstName("test3"));
fullNames.put(1, new PersonWithFullName("bobjohnson"));
fullNames.put(2, new PersonWithFullName("bobjames"));
fullNames.put(3, new PersonWithFullName("test1aaaa"));
fullNames.put(4, new PersonWithFullName("aliceSurname"));
Map<String, Set<String>> firstToFull = new HashMap<>();
List<String> firstNamesSorted = firstNames.values().stream().map(it -> it.firstName).sorted().collect(Collectors.toList());
List<String> fullNamesSorted = fullNames.values().stream().map(it -> it.fullName).sorted().collect(Collectors.toList());
int indexFirstName = 0;
int indexFullName = 0;
while (indexFirstName < firstNamesSorted.size() && indexFullName < fullNamesSorted.size()) {
String firstName = firstNamesSorted.get(indexFirstName);
String fullName = fullNamesSorted.get(indexFullName);
if (fullName.startsWith(firstName)) {
firstToFull.computeIfAbsent(firstName, n -> new HashSet<>())
.add(fullName);
indexFullName++;
} else {
if(compare(firstName, fullName) == 1) {
indexFullName++;
} else {
indexFirstName++;
}
}
}
int firstNamesSize = firstNamesSorted.size();
int i = 0;
while (firstToFull.size() < firstNamesSize) {
String name = firstNamesSorted.get(i);
firstToFull.computeIfAbsent(name, n -> new HashSet<>());
i++;
}
System.out.println(firstToFull);
}
private static int compare(String firstName, String fullName) {
String substring = fullName.substring(0, firstName.length());
return firstName.compareTo(substring);
}

Java List looping based of available size

I want to display only 12 sorted elements from myList. If the size is less than 12, say 5, or 3, or 1, still I need to loop and display only those available items.
Below is my code:
public class JavaApplication {
public static void main(String[] args) {
List<String> myList = new ArrayList<>();
myList.add("20150830");
myList.add("20141201");
myList.add("20150716");
myList.add("20151131");
myList.add("20141101");
myList.add("20150620");
myList.add("20150301");
myList.add("20150702");
myList.add("20150511");
Collections.sort(myList,Collections.reverseOrder());
for(int i = 0; i < myList.size(); i++) {
System.out.println(myList.get(i).toString());
}
}
}
This is a good use-case for streams.
myList.stream()
.sorted(Comparator.<String>reverseOrder())
.limit(12)
.forEach(System.out::println);
Just add one more condition in your loop to restrict the loop for 12.
for(int i = 0; i < myList.size() && i < 12 ; i++){
System.out.println(myList.get(i).toString());
}
You can try:
int maxValuesToDisplay=12;
int maxToIterate=(myList.size()<maxValuesToDisplay) ? myList.size() : maxValuesToDisplay;
for(int i = 0; i < maxToIterate; i++){
System.out.println(myList.get(i).toString());
}
Use List.subList(int fromIndex, int toIndex);
public class JavaApplication {
public static void main(String[] args) {
List<String> myList = new ArrayList<>();
myList.add("20150830");
myList.add("20141201");
myList.add("20150716");
myList.add("20151131");
myList.add("20141101");
myList.add("20150620");
myList.add("20150301");
myList.add("20150702");
myList.add("20150511");
Collections.sort(myList,Collections.reverseOrder());
int a = myList.size();
List subList = null;
if(a<12)
subList = myList.subList(0,a);
else subList = myList.subList(0,12);
//Print sublist now
}
}
You could use the Math.min() function and iterate the minimum of 12 and the list-size.
for(int i = 0; i < Math.min(myList.size(), 12); i++){
System.out.println(myList.get(i).toString());
}
You can use TreeSet :
public static void main(String[] args) {
Set<String> myList = new TreeSet<>();
myList.add("20150830");
myList.add("20141201");
myList.add("20150716");
myList.add("20151131");
myList.add("20141101");
myList.add("20150620");
myList.add("20150301");
myList.add("20150702");
myList.add("20150511");
int i = 0;
for(String s : myList){
System.out.println(s);
i++;
if(i >= 5) {
break;
}
}
}
And for reverse order :
public static void main(String[] args) {
TreeSet<String> myList = new TreeSet<>();
myList.add("20150830");
myList.add("20141201");
myList.add("20150716");
myList.add("20151131");
myList.add("20141101");
myList.add("20150620");
myList.add("20150301");
myList.add("20150702");
myList.add("20150511");
Iterator<String> it = myList.descendingIterator();
int i = 0;
while(it.hasNext()) {
String s = it.next();
System.out.println(s);
i++;
if (i >= 5) {
break;
}
}
}

Java - Sort one array based on values of another array?

I have an array of Strings that are instances of a class from external code that I would rather not change.
I also have an array of ints that was generated by calling a function on each object. So I have
A: [string1, string2, string3]
And
B: [40, 32, 34]
How do I easily sort A such that it is sorted in by the values of B. I have boost available. I want to sort A such that it is in the order:
[string2, string3, string1]
In javascript you could do this like:
B.sort(function(a,b){return A[B.indexOf(a)] < A[B.indexOf(b)];});
In java 8, you can do this
with a lambda:
String[] strings = new String[]{"string1", "string2", "string3"};
final int[] ints = new int[]{40, 32, 34};
final List<String> stringListCopy = Arrays.asList(strings);
ArrayList<String> sortedList = new ArrayList(stringListCopy);
Collections.sort(sortedList, (left, right) -> ints[stringListCopy.indexOf(left)] - ints[stringListCopy.indexOf(right)]);
Or better, with Comparator:
String[] strings = new String[]{"string1", "string2", "string3"};
final int[] ints = new int[]{40, 32, 34};
final List<String> stringListCopy = Arrays.asList(strings);
ArrayList<String> sortedList = new ArrayList(stringListCopy);
Collections.sort(sortedList, Comparator.comparing(s -> ints[stringListCopy.indexOf(s)]));
Short answer: I suggest that a separate class is created that holds the information about both the actual String and the boosting (the int). If you assume the following:
public class BoostString {
int boost;
String str;
public BoostString(int boost, String str) {
this.boost = boost;
this.str = str;
}
}
Then, you can sort your array by using a Comparator and it works especially nice with the Java 8 Streaming API.
String[] strings = {"string1", "string2", "string3"};
int[] boosts = {40, 32, 34};
final String[] sorted = IntStream.range(0, boosts.length)
.mapToObj(i -> new BoostString(boosts[i], strings[i])) // Create the instance
.sorted(Comparator.comparingInt(b -> b.boost)) // Sort using a Comparator
.map(b -> b.str) // Map it back to a string
.toArray(String[]::new); // And return an array
The Comparator in the example above is created using the Comparator.comparingInt method which is a convenient way of creating a Comparator for ints using Java 8.
Explanation: Typically when comparing objects in Java you use one of the built-in sorting functions such as Collections.sort where you provide your own Comparator. The Comparator interface is straightforward and looks like this:
public interface Comparator<T> {
int compare(T o1, T o2);
// Other default methods for Java 8
}
The return value is of type int and is described like this in the JavaDoc:
return a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
This works out-of-the-box when you are sorting Strings or int (or actually Integers) since they are Comparable – they sort of have a built-in natural sorting and for Strings this is in alphabetical order and for Integers this is sorted in ascending number order (see the JavaDoc for Comparable).
On a side note, there are other "pair" or "tuple" implementations available if you are using 3rd party libraries. You do not have to create your own "pair" of a String and int. One example is the Pair class from Apache Commons.
As #wassgren said, you can use streams, but you don't have to create a class, you can just use indexes:
String[] strings = {"string1", "string2", "string3"};
int[] boosts = {40, 32, 34};
String[] sorted = IntStream.range(0, boosts.length).boxed()
.sorted(Comparator.comparingInt(i -> boosts[i]))
.map(i -> strings[i])
.toArray(String[]::new);
First you create a stream of indexes, then you sort them acording to boosts and then you get the string in that index.
You can do something similar to your JS example in old style Java (but I would recommend joining your data together in an object as #wassgren suggests):
import java.util.*;
public class WeightSort {
public static void main(String[] args) {
String[] strings = new String[]{"string1", "string2", "string3"};
final int[] weights = new int[]{40, 32, 34};
final List<String> stringList = Arrays.asList(strings);
List<String> sortedCopy = new ArrayList<String>(stringList);
Collections.sort(sortedCopy, new Comparator<String>(){
public int compare(String left, String right) {
return weights[stringList.indexOf(left)] - weights[stringList.indexOf(right)];
}
});
System.out.println(sortedCopy);
}
}
I solved this problem by using Comparator interface.
import java.util.Comparator;
import java.util.Collections;
import java.util.List;
import java.util.Arrays;
public class ComparatorDemo {
public static void main(String[] args) {
List<Area> metaData = Arrays.asList(
new Area("Joe", 24),
new Area("Pete", 18),
new Area("Chris", 21),
new Area("Rose",21)
);
Collections.sort(metaData, new ResultComparator());
for(int i =0 ;metaData.size()>i;i++)
System.out.println(metaData.get(i).output);
}
}
class ResultComparator implements Comparator<Area> {
#Override
public int compare(Area a, Area b) {
return a.result < b.result ? -1 : a.result == b.result ? 0 : 1;
}
}
class Area{
String output;
int result;
Area(String n, int a) {
output = n;
result = a;
}
}
If you're constructing array B only to be used for this sorting, you can defer calculating it's values within A's compareTo(). In other words, calculate weights of strings only in comparisons during sorting.
package com.appkart.array;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
public class SortExample {
Map<String, Integer> map = new HashMap<String, Integer>();
Map<String, Integer> treemap = new TreeMap<String, Integer>(
new MyComparator(map));
public void addValueInMapAndSort() {
map.put("string1", 40);
map.put("string2", 32);
map.put("string3", 34);
System.out.println(map);
treemap.putAll(map);
System.out.println(treemap);
}
class MyComparator implements Comparator<String> {
Map<String, Integer> map;
public MyComparator(Map<String, Integer> map) {
this.map = map;
}
#Override
public int compare(String o1, String o2) {
if (map.get(o1) >= map.get(o2)) {
return 1;
} else {
return -1;
}
}
}
public static void main(String[] args) {
SortExample example = new SortExample();
example.addValueInMapAndSort();
}
}
Use Comparator for sorting according to value.
I had a similar problem, and solved it by coding a sorting algorithm which sorted an array of measures, and made identical swaps in the array of objects. Here is the code, with tests, best wishes and no promises:
package other;
import java.util.Arrays;
import java.util.Random;
/**
* Sorts an array of objects (<code>bags</code>) by a separate array of doubles (<code>measures</code>).
* It sorts into ascending order.
* <p>
* The <code>results</code> array is always a new array.
* <p>
* The algorithm used:<ul>
* <li> Is (I believe) a merge-sort, which would mean it is stable. (I haven't tested this.)
* <li> Efficiently exploits already ordered subsequences.
* <li> Requires the allocation of eight arrays: four of the baggage type, four of doubles, each the length of the original data.
* </ul>
* <p>
* A <code>NaN</code> in the <code>measures</code> - I haven't thought about that, and don't want to.
* <p>
* There is test code at the end of the class.
*/
public class SortBaggageByDouble {
public final Object [] results ;
protected final int length ;
public SortBaggageByDouble(Object[] bags, double[] measures) {
this.length = bags.length;
if (bags.length!=measures.length) throw new IllegalArgumentException("Mismatched lengths: payload array "+bags.length+", measures array "+measures.length);
this.results = new Object[length];
Object [] bagsA = new Object[length] ;
Object [] bagsB = new Object[length] ;
Object [] bagsC = new Object[length] ;
Object [] bagsD = new Object[length] ;
double [] measuresA = new double[length] ;
double [] measuresB = new double[length] ;
double [] measuresC = new double[length] ;
double [] measuresD = new double[length] ;
System.arraycopy(bags, 0, bagsA, 0, length);
System.arraycopy(measures, 0, measuresA, 0, length);
munge(length, 0, bagsA, bagsB, bagsC, bagsD, measuresA, measuresB, measuresC, measuresD);
}
private void munge(int inLengthA, int inLengthB, Object[] inBagsA, Object[] inBagsB, Object[] outBagsC, Object[] outBagsD, double[] inMeasuresA, double[] inMeasuresB, double[] outMeasuresC, double[] outMeasuresD) {
int outLengthC = 0 ;
int outLengthD = 0 ;
int cursorA = 0 ;
int cursorB = 0 ;
boolean toC = true ;
while(outLengthC+outLengthD<length) {
boolean fromA ;
if (cursorA>=inLengthA) {
fromA = false ;
} else if (cursorB>=inLengthB) {
fromA = true ;
} else {
fromA = inMeasuresA[cursorA] <= inMeasuresB[cursorB] ;
}
double tmpMeasure = fromA ? inMeasuresA[cursorA] : inMeasuresB[cursorB] ;
Object tmpBag = fromA ? inBagsA[cursorA] : inBagsB[cursorB] ;
if (fromA) cursorA ++ ; else cursorB ++ ;
if (toC) {
if (outLengthC==0 || (outMeasuresC[outLengthC-1]<=tmpMeasure)) {
outMeasuresC[outLengthC] = tmpMeasure ;
outBagsC[outLengthC] = tmpBag ;
outLengthC ++ ;
} else {
toC = false ;
outMeasuresD[outLengthD] = tmpMeasure ;
outBagsD[outLengthD] = tmpBag ;
outLengthD ++ ;
}
} else {
if (outLengthD==0 || (outMeasuresD[outLengthD-1]<=tmpMeasure)) {
outMeasuresD[outLengthD] = tmpMeasure ;
outBagsD[outLengthD] = tmpBag ;
outLengthD ++ ;
} else {
toC = true ;
outMeasuresC[outLengthC] = tmpMeasure ;
outBagsC[outLengthC] = tmpBag ;
outLengthC ++ ;
}
}
}
if (outLengthC==length) {
System.arraycopy(outBagsC, 0, results, 0, length);
} else {
munge(outLengthC, outLengthD, outBagsC, outBagsD, inBagsA, inBagsB, outMeasuresC, outMeasuresD, inMeasuresA, inMeasuresB);
}
}
/**
* Subclass to sort strings, with a result object <code>sortedStrings</code> which is of a useful type.
*/
public static class Strings extends SortBaggageByDouble {
public final String [] sortedStrings ;
public Strings(String[] in, double[] measures) {
super(in, measures);
this.sortedStrings = new String[results.length];
for (int i=0 ; i<results.length ; i++) sortedStrings[i] = (String) results[i] ;
}
}
/**
* Tests sorting - assumes there are no duplicates among the measures.
*/
private static class NoDuplicatesTest {
private NoDuplicatesTest(String[] shuffledStrings, double[] shuffledMeasures, String[] expectedStrings) {
SortBaggageByDouble.Strings sorter = new SortBaggageByDouble.Strings(shuffledStrings, shuffledMeasures);
if (!Arrays.equals(expectedStrings, sorter.sortedStrings)) throw new RuntimeException("Test failed");
}
}
private static class MultiseedNoDuplicatesTest {
private MultiseedNoDuplicatesTest(String[] orderedStrings, double[] orderedMeasures, int[] seeds) {
int length = orderedStrings.length;
for (int seed : seeds) {
Random random = new Random(seed);
int [] shuffleIndices = new int[length] ;
for (int i=0 ; i<length ; i++) shuffleIndices[i] = i ;
for (int i=1 ; i<length ; i++) {
int j = random.nextInt(i+1); // 'j' is in the range 0..i, bounds inclusive.
int tmp = shuffleIndices[i];
shuffleIndices[i] = shuffleIndices[j] ;
shuffleIndices[j] = tmp ;
}
String[] shuffledStrings = new String[length];
double[] shuffledMeasures = new double[length];
for (int i=0 ; i<length ; i++) {
shuffledStrings[shuffleIndices[i]] = orderedStrings[i] ;
shuffledMeasures[shuffleIndices[i]] = orderedMeasures[i] ;
}
if (false && 0<length && length<8) {
System.out.println("shuffleIndices is "+ stringfor(shuffleIndices));
System.out.println("shuffledStrings is "+ stringfor(shuffledStrings));
System.out.println("shuffledMeasures is "+ stringfor(shuffledMeasures));
}
new NoDuplicatesTest(shuffledStrings, shuffledMeasures, orderedStrings);
}
}
}
private static class MultilengthMultiseedNoDuplicatesTest {
MultilengthMultiseedNoDuplicatesTest(int[] lengths, int[] seeds) {
for (int i=0 ; i<lengths.length ; i++) {
int length = lengths[i] ;
String[] orderedStrings = new String[length] ;
double[] orderedMeasures = new double[length] ;
for (int j=0 ; j<length ; j++) {
orderedStrings[j] = "_"+j+"_" ;
orderedMeasures[j] = j ;
}
if (false && 0<length && length<8) {
System.out.println("orderedStrings is "+ stringfor(orderedStrings));
System.out.println("orderedMeasures is "+ stringfor(orderedMeasures));
}
new MultiseedNoDuplicatesTest(orderedStrings, orderedMeasures, seeds);
}
}
}
public static class ClassTest {
ClassTest() {
new MultilengthMultiseedNoDuplicatesTest(new int[]{0}, new int[]{8543, 45125});
new MultilengthMultiseedNoDuplicatesTest(new int[]{1}, new int[]{8543, 45125});
new MultilengthMultiseedNoDuplicatesTest(new int[]{2}, new int[]{8543, 45125, 4545, 785413});
new MultilengthMultiseedNoDuplicatesTest(new int[]{3, 4, 5, 6, 7, 8, 9, 10}, new int[]{8543, 45125, 4545, 785413});
new MultilengthMultiseedNoDuplicatesTest(new int[]{50, 100, 1000}, new int[]{474854, 43233});
////// Passed! Bye bye.
System.out.println("Passed test suite "+this.getClass().getCanonicalName());
}
}
public static String stringfor(int[] array) {
StringBuilder sb = new StringBuilder();
build(sb, array);
return sb.toString();
}
public static void build(StringBuilder sb, int[] array) {
for (int i=0 ; i<array.length ; i++) {
if (sb.length()>0) sb.append(' ');
sb.append(array[i]);
}
}
public static String stringfor(double[] array) {
StringBuilder sb = new StringBuilder();
build(sb, array);
return sb.toString();
}
public static void build(StringBuilder sb, double[] array) {
for (int i=0 ; i<array.length ; i++) {
if (sb.length()>0) sb.append(' ');
sb.append(array[i]);
}
}
public static String stringfor(String[] labels) {
StringBuffer sb = new StringBuffer();
String sep = "" ;
for (int i=0 ; i<labels.length ; i++) {
sb.append(sep);
String label = labels[i] ;
sb.append(label!=null ? label : "null");
sep = ", " ;
}
return sb.toString();
}
}
Maybe not exactly for that case, but for those who looking for answer how to sort one array of String based on another:
// Array of values, in a order of sorting
static final Map<String, Integer> ROUNDS_SORT = new HashMap<String, Integer>();
static {
ROUNDS_SORT.put("f", 0);
ROUNDS_SORT.put("s", 1);
ROUNDS_SORT.put("q", 2);
ROUNDS_SORT.put("r16", 3);
ROUNDS_SORT.put("r32", 4);
ROUNDS_SORT.put("r64", 5);
}
// Your array to be sorted
static ArrayList<String> rounds = new ArrayList<String>() {{
add("f");
add("q");
add("q");
add("r16");
add("f");
}};
// implement
public List<String> getRoundsSorted() {
Collections.sort(rounds, new Comparator<String>() {
#Override
public int compare(String p1, String p2) {
return Integer.valueOf(ROUNDS_SORT.get(p1)).compareTo(Integer.valueOf(ROUNDS_SORT.get(p2)));
}
});
return rounds;
}
In java you need to have two arrays one copy to sort off and the array you want to sort.
with a lambda:
String[] strings = new String[]{"string1", "string2", "string3", "string4"};
final int[] ints = new int[]{100, 88, 92, 98};
final List<String> stringListCopy = Arrays.asList(strings);
ArrayList<String> sortedList = new ArrayList(stringListCopy);
Collections.sort(sortedList, (left, right) -> ints[stringListCopy.indexOf(left)] - ints[stringListCopy.indexOf(right)]);
Or with Comparator:
String[] strings = new String[]{"string1", "string2", "string3", "string4"};
final int[] ints = new int[]{100, 92, 88, 98};
final List<String> stringListCopy = Arrays.asList(strings);
ArrayList<String> sortedList = new ArrayList(stringListCopy);
Collections.sort(sortedList, Comparator.comparing(s -> ints[stringListCopy.indexOf(s)]));
Create an array of longs with the top 32 bits being the sorting integers and the bottom 32 bits being the array indexes. Sort that array then use the now sorted indexes to build a sorted string array.
String[] strings = new String[]{"string1", "string2", "string3"};
final int[] ints = new int[]{40, 32, 34};
final long[] longs = new long[ints.length];
for (int i = 0; i < ints.length; i++) {
longs[i] = (long)ints[i] << 32 | (long)i;
}
Arrays.sort(longs);
String[] sortedStrings = new String[strings.length];
for(int i = 0; i < longs.length; i++) {
sortedStrings[i] = strings[(int)longs[i]];
}
System.out.println(Arrays.asList(sortedStrings));
I believe this is algorithmically the same as Ofek's stream-based solution above, but uses more traditional Java.
A feature of the algorithm is that if two entries have the same sorting integer they will retain their original sequences with respect to each other.
Make a TreeMap<Integer, List<ObjectTypeFromA>> where the map key is the values in B, and the map values are the values in A (using a list to allow for duplicate keys). It will be sorted in the order of B by definition.
public static void main(String[] args) {
String[] strings = { "string1", "string2", "string3", "string4" };
int[] ints = { 40, 32, 32, 34 };
System.out.println(Arrays.toString(getSortedStringArray(strings, ints)));
}
public static String[] getSortedStringArray(String[] strings, int[] order) {
Map<Integer, List<String>> map = new TreeMap<>();
for (int i = 0; i < strings.length; i++) {
if (!map.containsKey(order[i])) {
map.put(order[i], new LinkedList<String>());
}
map.get(order[i]).add(strings[i]);
}
String[] ret = new String[strings.length];
int i = 0;
for (Map.Entry<Integer, List<String>> mapEntry : map.entrySet()) {
for (String s : mapEntry.getValue()) {
ret[i++] = s;
}
}
return ret;
}

Comparting two ArrayList<String> lists in Java

Okay... So what I've been trying to do is compare two lists: words and d. The words they have in common need to be added to a third list: realWords.
Dictionary is just a list in a different class that has a bunch of words in it.
List<String> realWords = new ArrayList<String>();
Dictionary d = new Dictionary();
These are the things I've tried and haven't worked (and by "worked" I mean the output is nothing, no errors):
Attempt 1
List<String> realWords = new ArrayList<String>(words);
realWords.retainAll(d);
Attempt 2
for(int i = 0; i < words.size(); i++) {
if (d.contains(words.get(i))){
realWords.add(words.get(i));
}
}
Attempt 3
for(String word : words) {
if (d.contains(word)) {
realWords.add(word);
}
}
Attempt 4
for (int i = 0; i < words.size(); i++) {
for (int j = 0; i < d.size(); i++) {
if(words.get(i) == d.get(j)) {
realWords.add(words.get(i));
}
}
}
And then after that portion of code I'm missing:
return realWords;
Thanks in advance!
Edit1: The code for Dictionary.java is:
package a1;
import java.util.*;
public class Dictionary extends ArrayList<String> {
public Dictionary() {
this.add("abalone");
this.add("abandon");
this.add("abashed");
this.add("abashes");
this.add("abasing");
this.add("abating");
this.add("abdomen");
this.add("abducts");
this.add("abetted");
this.add("abetter");
this.add("abettor");
this.add("abiding");
this.add("ability");
this.add("abjured");
this.add("abjures");
this.add("abolish");
this.add("aborted");
this.add("abounds");
this.add("abraded");
// and then more words
}
}
NOTE: This code was provided to us and cannot be changed.
The following code has the following output: [abalone, abolish]
The problem must be somewhere else. Are you sure that "words" contains valid words? Try outputting it and checking manually.
public class Example {
public static class Dictionary extends ArrayList<String> {
public Dictionary() {
this.add("abalone");
this.add("abandon");
this.add("abashed");
this.add("abashes");
this.add("abasing");
this.add("abating");
this.add("abdomen");
this.add("abducts");
this.add("abetted");
this.add("abetter");
this.add("abettor");
this.add("abiding");
this.add("ability");
this.add("abjured");
this.add("abjures");
this.add("abolish");
this.add("aborted");
this.add("abounds");
this.add("abraded");
// and then more words
}
}
public static void main(String[] args) {
List<String> realWords = new ArrayList<String>(
Arrays.asList("abalone", "foobar", "abolish"));
Dictionary d = new Dictionary();
realWords.retainAll(d);
System.out.println(realWords);
}
}
EDIT: Your other attempts are functionally identical, they have the same complexity (O(words.size() * d.size()) but are longer and less obvious/clear.
The code works fine, please debug your code. See the output for reference.
public static void main(String[] args) {
List<String> words = new ArrayList<String>();
words.add("abashes");
words.add("sdqad");
words.add("abducts");
words.add("sadadads");
List<String> realWords = new ArrayList<String>();
Dictionary d = new Dictionary();
for (int i = 0 ; i < words.size() ; i++) {
if (d.contains(words.get(i))) {
realWords.add(words.get(i));
}
}
System.out.println(realWords);
}
output
[abashes, abducts]
Using Java 8 streams I would suggest:
List<Strings> realWords = words.stream()
.filter(d::contains).collect(Collectors.toList());
You can use an enhance for loop
List<String> realWords = new ArrayList<>();
Dictionary d = new Dictionary();
List<String> words = new ArrayList<String>();
words.add("abetted");
words.add("ability");
for (String word : words) {
if (d.contains(word)) {
realWords.add(word);
}
}
System.out.println(realWords);
}
}

arraylist loading gives me interesting output

i have this simple method:
public static Map<String, ArrayList<String>> szamolando = new HashMap<String,ArrayList<String>>();
ArrayList<String> outputs = new ArrayList<String>();
for(int i = 0;i<2;i++){
tombFeltolt("a"+i);
}
public void tombFeltolt(String kimenet) {
outputs.clear();
System.out.println("1");
outputs.add(min);
System.out.println("2");
outputs.add(max);
System.out.println("3");
outputs.add("65535");
szamolando.put(kimenet, outputs);
}
than i've got this output: 1 2 3 2
why do i got this?What is wrong with my method?Thank You for your answers!
Edit:
okay here is the complete code:
public static Map<String, ArrayList<String>> szamolando = new HashMap<String, ArrayList<String>>();
static ArrayList<String> outputs = new ArrayList<String>();
static String min, max;
public static void main(String[] args) {
for (int i = 0; i < 2; i++) {
if (i == 0) {
min = "10";
max = "20";
} else {
min = "9";
max = "8";
}
tombFeltolt("a" + i);
}
for (String name : szamolando.keySet()) {
String key = name.toString();
String value = szamolando.get(name).toString();
System.out.println("ASS " + key + " " + value);
}
}
public static void tombFeltolt(String kimenet) {
outputs.clear();
System.out.println("1");
outputs.add(min);
System.out.println("2");
outputs.add(max);
System.out.println("3");
outputs.add("65535");
szamolando.put(kimenet, outputs);
}
and here is my output:
ASS a0 [9, 8, 65535]
ASS a1 [9, 8, 65535]
you have to change this:
static ArrayList<String> outputs = new ArrayList<String>();
to this:
static ArrayList<String> outputs = null;
and put this line into your 'for' loop:
outputs = new ArrayList<String>();
This is the source of your problem
When you do a clear, it will clear the ArrayList which still references to the existing ArrayList which will clear the stored list as well coz it has stored the reference.
if you want 10, 20, 65535 use new list everytime.
outputs.clear();

Categories

Resources