Related
I have two Strings
String 1 = "In the name of God, the Gracious, the Merciful."
String 2 = "In the name of God the Gracious the Merciful"
I want to match each word of string two with string one. I have used below code but it's not working fine for above case
private void printDiff(final Context context, String sentence1, String sentence2) {
String[] array1 = sentence1.split(" ");
String[] array2 = sentence2.split(" ");
SpannableStringBuilder sb = new SpannableStringBuilder(sentence1);
for (int i = 0; i < array1.length; i++) {
int colorRes;
if (i < array2.length) {
colorRes = array1[i].equalsIgnoreCase(array2[i]) ? R.color.colorPrimary : R.color.colorAccent;
} else {
colorRes = R.color.black;
}
int startIndex = getStartIndexOf(array1, i);
int endIndex = startIndex + array1[i].length();
sb.setSpan(new ForegroundColorSpan(ContextCompat.getColor(context, colorRes)), startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
public static int getStartIndexOf(String[] array, int index) {
int count = 0;
for (int i = 0; i < index; i++) {
count += array[i].length();
count++;
}
return count;
}
Can anyone help me
I want output like this. Because all characters matched
You can convert your String to character array and can match them by characters
s1 = s1.replacereplace(" ", "");
s1 = s1.replacereplace(",", "");
s2 = s2.replacereplace(" ", "");
char[] a = s1.toCharArray();
char[] b = s2.toCharArray();
int j=0;
for(int i=0; <a.length; i++){
if(a[i]==b[j]){
}
j++;
}
try this code to check the differences of your string
public class TestActivity extends AppCompatActivity {
String string1 = "In the name of God, the Gracious, the Merciful.";
String string2 = "In the name of God the Gracious the mercifuls";
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
List<String> stringList = new ArrayList<>(Arrays.asList(string2.split(" "))); // Split the string into list
// compare the list with the source of the string, if match put into the list of result
List<String> result = stringList.stream().filter(new Predicate<String>() {
#Override
public boolean test(String s) {
// return string1.contains(s); // case sensitive
return Pattern.compile(Pattern.quote(s), Pattern.CASE_INSENSITIVE).matcher(string1).find(); // case insensitive
}
}).collect(Collectors.toList());
// check the match results
if(result.size()<stringList.size()){
Log.d("test", "onCreate: not match");
}else{
Log.d("test", "onCreate: match");
}
}
}
Hope can help you to resolve your problems
so in-order to use the code above needed to edit gradle. Open the app.gradle of yours and put this into your gradle
android {
compileSdkVersion 28
defaultConfig {
.....
}
buildTypes {
release {
.....
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
I have an Android app with a MultiSelectListPreference, and I'm using the onPreferenceChange() method to update the Preference's summary. I've managed to write the code that updates the summary based on the newValues parameter, but the contents of the Object do not match the actual options selected by the user.
Here is my code:
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference instanceof MultiSelectListPreference) {
List<String> newValues = new ArrayList<>((HashSet<String>) newValue);
MultiSelectListPreference pref = (MultiSelectListPreference) preference;
ArrayList<String> newSummary = new ArrayList<>();
ArrayList<CharSequence> values = new ArrayList<>(Arrays.asList(pref.getEntryValues()));
for (int i = 0; i < newValues.size(); i++) {
int currentIndex = findIndexOfString(values, newValues.get(i).replaceAll(" ", ""));
String title = (currentIndex >= 0) ? pref.getEntries()[currentIndex].toString().replaceAll(" ", "") : "";
newSummary.add(title);
}
pref.setSummary(TextUtils.join(", ", newSummary));
}
return true;
}
private static int findIndexOfString(List<CharSequence> list, String s) {
for (int i = 0; i < list.size(); i++) {
if (s.equals(list.get(i).toString().replaceAll(" ", ""))) {
return i;
}
}
return -1;
}
This is the code I'm using to set summary based on the newValue Object received from onPreferenceChange(), which contains the values stored as a preference. (Not good for the summary)
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference instanceof MultiSelectListPreference) {
List<String> newValues = new ArrayList<>((HashSet<String>) newValue);
pref.setSummary(TextUtils.join(", ", getSummaryListFromValueList(newValues)));
}
return true;
}
private List<String> getSummaryListFromValueList(List<String> valueList) {
String[] allSummaries = getResources().getStringArray(R.array.pref_notif);
String[] allValues = getResources().getStringArray(R.array.pref_notif_values);
List<String> summaryList = new ArrayList<>();
for (int i = 0; i < allValues.length; i++) {
for (String value : valueList) {
if (allValues[i].equals(value)) {
summaryList.add(allSummaries[i]);
}
}
}
return summaryList;
}
I want to show my numbers in money format and separate digits like the example below:
1000 -----> 1,000
10000 -----> 10,000
100000 -----> 100,000
1000000 -----> 1,000,000
Thanks
Another approach :
NumberFormat format = NumberFormat.getCurrencyInstance();
format.setMaximumFractionDigits(0);
format.setCurrency(Currency.getInstance("EUR"));
format.format(1000000);
This way, it's displaying 1 000 000 € or 1,000,000 €, depending on device currency's display settings
You need to use a number formatter, like so:
NumberFormat formatter = new DecimalFormat("#,###");
double myNumber = 1000000;
String formattedNumber = formatter.format(myNumber);
//formattedNumber is equal to 1,000,000
Hope this helps!
double number = 1000000000.0;
String COUNTRY = "US";
String LANGUAGE = "en";
String str = NumberFormat.getCurrencyInstance(new Locale(LANGUAGE, COUNTRY)).format(number);
//str = $1,000,000,000.00
Currency formatter.
public static String currencyFormat(String amount) {
DecimalFormat formatter = new DecimalFormat("###,###,##0.00");
return formatter.format(Double.parseDouble(amount));
}
Use this:
int number = 1000000000;
String str = NumberFormat.getNumberInstance(Locale.US).format(number);
//str = 1,000,000,000
This Method gives you the exact output which you need:
public String currencyFormatter(String num) {
double m = Double.parseDouble(num);
DecimalFormat formatter = new DecimalFormat("###,###,###");
return formatter.format(m);
}
Try the following solution:
NumberFormat format = NumberFormat.getCurrencyInstance();
((TextView)findViewById(R.id.text_result)).setText(format.format(result));
The class will return a formatter for the device default currency.
You can refer to this link for more information:
https://developer.android.com/reference/java/text/NumberFormat.html
Here's a kotlin Extension that converts a Double to a Currency(Nigerian Naira)
fun Double.toRidePrice():String{
val format: NumberFormat = NumberFormat.getCurrencyInstance()
format.maximumFractionDigits = 0
format.currency = Currency.getInstance("NGN")
return format.format(this.roundToInt())
}
Use a Formatter class
For eg:
String s = (String.format("%,d", 1000000)).replace(',', ' ');
Look into:
http://developer.android.com/reference/java/util/Formatter.html
The way that I do this in our app is this:
amount.addTextChangedListener(new CurrencyTextWatcher(amount));
And the CurrencyTextWatcher is this:
public class CurrencyTextWatcher implements TextWatcher {
private EditText ed;
private String lastText;
private boolean bDel = false;
private boolean bInsert = false;
private int pos;
public CurrencyTextWatcher(EditText ed) {
this.ed = ed;
}
public static String getStringWithSeparator(long value) {
DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
String f = formatter.format(value);
return f;
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
bDel = false;
bInsert = false;
if (before == 1 && count == 0) {
bDel = true;
pos = start;
} else if (before == 0 && count == 1) {
bInsert = true;
pos = start;
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
lastText = s.toString();
}
#Override
public void afterTextChanged(Editable s) {
ed.removeTextChangedListener(this);
StringBuilder sb = new StringBuilder();
String text = s.toString();
for (int i = 0; i < text.length(); i++) {
if ((text.charAt(i) >= 0x30 && text.charAt(i) <= 0x39) || text.charAt(i) == '.' || text.charAt(i) == ',')
sb.append(text.charAt(i));
}
if (!sb.toString().equals(s.toString())) {
bDel = bInsert = false;
}
String newText = getFormattedString(sb.toString());
s.clear();
s.append(newText);
ed.addTextChangedListener(this);
if (bDel) {
int idx = pos;
if (lastText.length() - 1 > newText.length())
idx--; // if one , is removed
if (idx < 0)
idx = 0;
ed.setSelection(idx);
} else if (bInsert) {
int idx = pos + 1;
if (lastText.length() + 1 < newText.length())
idx++; // if one , is added
if (idx > newText.length())
idx = newText.length();
ed.setSelection(idx);
}
}
private String getFormattedString(String text) {
String res = "";
try {
String temp = text.replace(",", "");
long part1;
String part2 = "";
int dotIndex = temp.indexOf(".");
if (dotIndex >= 0) {
part1 = Long.parseLong(temp.substring(0, dotIndex));
if (dotIndex + 1 <= temp.length()) {
part2 = temp.substring(dotIndex + 1).trim().replace(".", "").replace(",", "");
}
} else
part1 = Long.parseLong(temp);
res = getStringWithSeparator(part1);
if (part2.length() > 0)
res += "." + part2;
else if (dotIndex >= 0)
res += ".";
} catch (Exception ex) {
ex.printStackTrace();
}
return res;
}
Now if you add this watcher to your EditText, as soon as user enter his number, the watcher decides whether it needs separator or not.
i used this code for my project and it works:
EditText edt_account_amount = findViewById(R.id.edt_account_amount);
edt_account_amount.addTextChangedListener(new DigitFormatWatcher(edt_account_amount));
and defined class:
public class NDigitCardFormatWatcher implements TextWatcher {
EditText et_filed;
String processed = "";
public NDigitCardFormatWatcher(EditText et_filed) {
this.et_filed = et_filed;
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable editable) {
String initial = editable.toString();
if (et_filed == null) return;
if (initial.isEmpty()) return;
String cleanString = initial.replace(",", "");
NumberFormat formatter = new DecimalFormat("#,###");
double myNumber = new Double(cleanString);
processed = formatter.format(myNumber);
//Remove the listener
et_filed.removeTextChangedListener(this);
//Assign processed text
et_filed.setText(processed);
try {
et_filed.setSelection(processed.length());
} catch (Exception e) {
// TODO: handle exception
}
//Give back the listener
et_filed.addTextChangedListener(this);
}
}
Updated 2022 answer
Try this snippet. It formats a number in string complete with the currency & setting fractional digits.
Upvote if this helped you! :)
/**
* Formats amount in string to human-readable amount (separated with commas
* & prepends currency symbol)
*
* #param amount The amount to format in String
* #return The formatted amount complete with separators & currency symbol added
*/
public static String formatCurrency(String amount) {
String formattedAmount = amount;
try {
if (amount == null || amount.isEmpty())
throw new Exception("Amount is null/empty");
Double amountInDouble = Double.parseDouble(amount);
NumberFormat numberFormat = NumberFormat.getCurrencyInstance(new Locale("en", "IN"));
numberFormat.setMaximumFractionDigits(2);
numberFormat.setMinimumFractionDigits(2);
formattedAmount = numberFormat.format(amountInDouble);
} catch (Exception exception) {
exception.printStackTrace();
return formattedAmount;
}
return formattedAmount;
}
private val currencyFormatter = NumberFormat.getCurrencyInstance(LOCALE_AUS).configure()
private fun NumberFormat.configure() = apply {
maximumFractionDigits = 2
minimumFractionDigits = 2
}
fun Number.asCurrency(): String {
return currencyFormatter.format(this)
}
And then just use as
val x = 100000.234
x.asCurrency()
If you have the value stored in a String like me, which was coming from the server like "$20000.00".
You can do something like this in Kotlin (JetpackCompose):
#Composable
fun PrizeAmount(
modifier: Modifier = Modifier,
prize: String,
)
{
val currencyFormat = NumberFormat.getCurrencyInstance(Locale("en", "US"))
val text = currencyFormat.format(prize.substringAfter("$").toDouble())
...
}
Output: "$20,000.00"
NumberFormat.getCurrencyInstance(Locale("ES", "es")).format(number)
here is a kotlin version to Format Currency, here i'm getting an argument from another fragment from an input Field then it will be set in the textView in the main Fragment
fun formatArgumentCurrency(argument : String, textView: TextView) {
val valueText = requireArguments().get(argument).toString()
val dec = DecimalFormat("#,###.##")
val number = java.lang.Double.valueOf(valueText)
val value = dec.format(number)
val currency = Currency.getInstance("USD")
val symbol = currency.symbol
textView.text = String.format("$symbol$value","%.2f" )
}
You can easily achieve this with this small simple library.
https://github.com/jpvs0101/Currencyfy
Just pass any number, then it will return formatted string, just like that.
currencyfy (500000.78); // $ 500,000.78 //default
currencyfy (500000.78, false); // $ 500,001 // hide fraction (will round off automatically!)
currencyfy (500000.78, false, false); // 500,001 // hide fraction & currency symbol
currencyfy (new Locale("en", "in"), 500000.78); // ₹ 5,00,000.78 // custom locale
It compatible with all versions of Android including older versions!
I am developing an app in which i have to assign integer values to different string of words. For Example I want to assign:
John = 2
Good = 3
Person= 7
Now these John, Good and person are strings while 2,3 and 7 are int values. But I am so confused about how to implement that. I read many things about how to convert int to string and string to int but this is different case.
I am giving option to user to enter a text in editText and if for example User enters "Hello John you are a good person" then this line output will be 12 as all the three words John, Good and person are there in the input text. Can you tell me how to achieve that?
I am stuck here is my little code:
String s = "John";
int s_value= 2;
now I want to assign this 2 to John so that whenever user give input and it contains John then the value 2 is shown for John. Please Help as I am just a beginner level programmer
Here is my code (Edited)
String input = "John good person Man";
Map<String, Integer> map = new HashMap<>();
map.put("John", 2);
map.put("Good", 3);
map.put("Person", 7);
//int number = map.get("Good");
String[] words = input.split(" ");
ArrayList<String> wordsList = new ArrayList<String>();
for(String word : words)
{
wordsList.add(word);
}
for (int ii = 0; ii < wordsList.size(); ii++) {
// get the item as string
for (int j = 0; j < stopwords.length; j++) {
if (wordsList.contains(stopwords[j])) {
wordsList.remove(stopwords[j]);//remove it
}
}
}
for (String str : wordsList) {
Log.e("msg", str + " ");
}
As u see i applied code of you and then i want to split my main string so that each word of that string compares with the strings that are in the Map<>. Now i am confused what to write in the for loop ( 'stopwords' will be replaced by what thing?)
You can use a Map<String, Integer> to map words to numbers:
Map<String, Integer> map = new HashMap<>();
map.put("John", 2);
map.put("Good", 3);
map.put("Person", 7);
and then query the number given a word:
int number = map.get("John"); // will return 2
UPDATE
The following code iterates over a collection of words and adds up the values that the words match to:
List<String> words = getWords();
int total = 0;
for (String word : words) {
Integer value = map.get(word);
if (value != null) {
total += value;
}
}
return total;
I would use a Dictionary for this. You can add a string and an int (or anything else actually) value for that string.
Dictionary<string, int> d = new Dictionary<string, int>();
d.Add("John", 2);
d.Add("Good", 3);
d.Add("Person", 7);
You can use String contains to achieve this. Following is the code:
String input = "John you are a good person";
String s1 = "John";
String s2 = "good";
String s3 = "person";
int totScore =0;
if(input.contains(s1)) {
totScore=totScore+2;
}
else if (input.contains(s2)) {
totScore=totScore+3;
}
else if (input.contains(s3)) {
totScore=totScore+7;
}
System.out.print(totScore);
You can use class like.
class Word{
String wordName;
int value;
public Word(String wordName, int value){
this.wordName = wordName;
this.value = value;
}
// getter
public String getWordName(){
return this.wordName;
}
public int getValue(){
return this.value;
}
// setter
public void setWordName(String wordName){
this.wordName = wordName;
}
public void zetValue(int value){
this.value = value;
}
}
You can create an object of the word
Word person = new Word("Person",3);
I want to save/recall an integer array using SharedPreferences. Is this possible?
You can try to do it this way:
Put your integers into a string, delimiting every int by a character, for example a comma, and then save them as a string:
SharedPreferences prefs = getPreferences(MODE_PRIVATE);
int[] list = new int[10];
StringBuilder str = new StringBuilder();
for (int i = 0; i < list.length; i++) {
str.append(list[i]).append(",");
}
prefs.edit().putString("string", str.toString());
Get the string and parse it using StringTokenizer:
String savedString = prefs.getString("string", "");
StringTokenizer st = new StringTokenizer(savedString, ",");
int[] savedList = new int[10];
for (int i = 0; i < 10; i++) {
savedList[i] = Integer.parseInt(st.nextToken());
}
You can't put Arrays in SharedPreferences, but you can workaround:
private static final String LEN_PREFIX = "Count_";
private static final String VAL_PREFIX = "IntValue_";
public void storeIntArray(String name, int[] array){
SharedPreferences.Editor edit= mContext.getSharedPreferences("NAME", Context.MODE_PRIVATE).edit();
edit.putInt(LEN_PREFIX + name, array.length);
int count = 0;
for (int i: array){
edit.putInt(VAL_PREFIX + name + count++, i);
}
edit.commit();
}
public int[] getFromPrefs(String name){
int[] ret;
SharedPreferences prefs = mContext.getSharedPreferences("NAME", Context.MODE_PRIVATE);
int count = prefs.getInt(LEN_PREFIX + name, 0);
ret = new int[count];
for (int i = 0; i < count; i++){
ret[i] = prefs.getInt(VAL_PREFIX+ name + i, i);
}
return ret;
}
Here's my version, based on Egor's answer. I prefer not to use StringBuilder unless I'm building an enourmous string, but thanks to Egor for using StringTokenizer -- haven't made much use of this in the past, but it's very handy! FYI, this went in my Utility class:
public static void saveIntListPrefs(
String name, Activity activity, List<Integer> list)
{
String s = "";
for (Integer i : list) {
s += i + ",";
}
Editor editor = activity.getPreferences(Context.MODE_PRIVATE).edit();
editor.putString(name, s);
editor.commit();
}
public static ArrayList<Integer> readIntArrayPrefs(String name, Activity activity)
{
SharedPreferences prefs = activity.getPreferences(Context.MODE_PRIVATE);
String s = prefs.getString(name, "");
StringTokenizer st = new StringTokenizer(s, ",");
ArrayList<Integer> result = new ArrayList<Integer>();
while (st.hasMoreTokens()) {
result.add(Integer.parseInt(st.nextToken()));
}
return result;
}
I like to use JSON, which can be stored and retrieved as a string, to represent any complex data in SharedPreferences.
So, in the case of an int array:
public void setPrefIntArray(String tag, int[] value)
{
SharedPreferences.Editor prefEditor = PreferenceManager.getDefaultSharedPreferences(context)
.edit();
String s;
try
{
JSONArray jsonArr = new JSONArray();
for (int i : value)
jsonArr.put(i);
JSONObject json = new JSONObject();
json.put(tag, jsonArr);
s = json.toString();
}
catch(JSONException excp)
{
s = "";
}
prefEditor.putString(tag, s);
prefEditor.commit();
}
public int[] getPrefIntArray(String tag, int[] defaultValue)
{
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
String s = pref.getString(tag, "");
try
{
JSONObject json = new JSONObject(new JSONTokener(s));
JSONArray jsonArr = json.getJSONArray(tag);
int[] result = new int[jsonArr.length()];
for (int i = 0; i < jsonArr.length(); i++)
result[i] = jsonArr.getInt(i);
return result;
}
catch(JSONException excp)
{
return defaultValue;
}
}
The beauty is that the same idea can be applied to any other complex data representable as a JSON.
Two solutions:
(1) Use http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html
It has split/join functions that let you join and split the integers in one liners:
StringUtils.join([1, 2, 3], ';') = "1;2;3"
StringUtils.split("1;2;3", ';') = ["1", "2", "3"]
You'd still have to convert the strings back to integers, though.
Actually, for splitting java.lang.String.split() will work just as fine:
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split(java.lang.String)
(2) Use the SharedPreferences.putStringSet() (API 11):
SharedPreferences.Editor editor = preferences.edit();
int count = this.intSet.size();
if (count > 0) {
Set<String> theSet = new HashSet<String>();
for (Long l : this.intSet) {
theSet.add(String.valueOf(l));
}
editor.putStringSet(PREFS_KEY, theSet);
} else {
editor.remove(PREFS_KEY);
}
editor.commit();
And to get it back:
Set<String> theSet = this.preferences.getStringSet(PREFS_KEY, null);
if (theSet != null && !theSet.isEmpty()) {
this.intSet.clear();
for (String s : theSet) {
this.intSet.add(Integer.valueOf(s));
}
}
This code does not catch the NPEs or NumberFormatExceptions because the intSet is otherwise assured to not contain any nulls. But of course, if you cannot assure that in your code you should surround this with a try/catch.
Here is how the "convert to comma-separated String" solution could look in Kotlin, implemented as extension functions:
fun SharedPreferences.Editor.putIntArray(key: String, value: IntArray): SharedPreferences.Editor {
return putString(key, value.joinToString(
separator = ",",
transform = { it.toString() }))
}
fun SharedPreferences.getIntArray(key: String): IntArray {
with(getString(key, "")) {
with(if(isNotEmpty()) split(',') else return intArrayOf()) {
return IntArray(count(), { this[it].toInt() })
}
}
}
That way you can use putIntArray(String, IntArray) and getIntArray(String) just like the other put and set methods:
val prefs = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
prefs.edit().putIntArray(INT_ARRAY_TEST_KEY, intArrayOf(1, 2, 3)).apply()
val intArray = prefs.getIntArray(INT_ARRAY_TEST_KEY)
I went for the below solution, it's the least verbose of what I could see in this thread (in my case I wanted to have a set as a collection). "value" is the of type Set<Int>.
Save:
sharedPreferences.edit {
if (value.isNotEmpty()) {
putStringSet(key, hashSetOf(*value.map { it.toString() }.toTypedArray()))
} else {
remove(key)
}
}
Retrieve:
val stringSet = sharedPreferences.getStringSet(key, null)
if (stringSet.isNullOrEmpty()) return emptySet()
return setOf<Int>(*stringSet.map { Integer.valueOf(it) }.toTypedArray())
You can only save primitive values in sharedPreference. Use Sqlite instead.