looping through the alphabet as String - java

I want to loop through the alphabet with a for loop and add each letter to my HashMap
for(char alphabet = 'A'; alphabet <= 'Z';alphabet++) {
System.out.println(alphabet);
}
doesn't work for me, because my HashMap is of form
HashMap<String, HashMap<String, Student>> hm;
I need my iterator to be a string, but
for(String alphabet = 'A'; alphabet <= 'Z';alphabet++) {
System.out.println(alphabet);
}
doesn't work.
Basically, I want to do this:
for i from 'A' to 'Z' do
hm.put(i, null);
od
Any ideas?

Basically convert the char to a string, like this:
for(char alphabet = 'A'; alphabet <= 'Z';alphabet++) {
hm.put(""+alphabet, null);
}
Although ""+alphabet is not efficient as it boils down to a call to StringBuilder
The equivalent but more effective way can be
String.valueOf(alphabet)
or
Character.toString(alphabet)
which are actually the same.

You cannot assign a char to a String, or to increment a string with ++. You can iterate on the char the way you did in your first sample, and convert that char to a String, like this:
for(char letter = 'A'; letter <= 'Z'; letter++) {
String s = new String(new char[] {letter});
System.out.println(s);
}

First problem: When you work with a HashMap, you are supposed to map a key to a value. You don't just put something in a hash map. The letter you wanted to put, is it a value? Then what is the key? Is it a key? Then what is the value?
You might think that using "null" as a value is a good idea, but you should ask yourself: in that case, should I use a map at all? Maybe using a HashSet is a better idea?
The second problem is that a HashMap, like all java collections, only takes objects - both as keys and as values. If you want to use a character as a key, you could define your map as Map<Character,Map<String,Student>>, which will auto-box your character (convert it to an object of type Character) or you could convert the character to a string using
Character.toString(alphabet);

In Java 8 with Stream API, you can do this.
IntStream.rangeClosed('A', 'Z').mapToObj(var -> String.valueOf((char) var)).forEach(System.out::println);

Related

Convert a String into a set<Character> using a Stream java 8

private static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
SortedSet<Character> set= new TreeSet<Character>();
for (int i = 0; i < ALPHABET.length(); i++) {
set.add(new Character(ALPHABET.charAt(i)));
}
I would like to convert this for loop in Java 8 way. It could be better if using a stream. Output will be the "set" object with contains the Character.
String has a method which will give you a stream of characters. It's actually an IntStream so we just need to convert them to Characters and then collect to a set.
"foo".chars()
.mapToObj(chr -> (char) chr) // autoboxed to Character
.collect(Collectors.toSet());
or use TreeSet::new as others have shown if you need the set to be sorted.
IntStream.range(0, ALPHABET.length())
.mapToObj(ALPHABET::charAt)
.collect(Collectors.toCollection(TreeSet::new));
I think this is the simplest way, preserving the requirement of using a TreeSet. Notice that there's no need to iterate over the input string using indexes, you can directly iterate over its characters.
SortedSet<Character> set =
ALPHABET.chars()
.mapToObj(c -> (char) c)
.collect(Collectors.toCollection(TreeSet::new));

Change lowercase and uppercase of characters in java

If I want to create a dictionary where the user can create a custom alphabet (that still uses unicode) Is there a way to change lowercase and uppercase mapping of the characters?
Let's say I want the lowercase of 'I' to be 'ı' instead of 'i' or upperCase of 'b' to be 'P' instead of 'B' so that System.out.println("PAI".toLowerCase()); would write baı to the console.
I suppose I can create a method toLowerCase(String s) that first replaces "P" with "b"s then converts to lowercase but wouldn't that be slower when searching through a dictionary of hundreds of thousands of words?
The toLowerCase(String s) uses the locale to decide how to convert the characters, you should have to define your own locale and then, for example, load it as the default locale via Locale.setDefault(Locale) before executing the toLowerCase(String s)
No, it would not be slower because you are simply traversing through the array and not modifying the position of any object which would result in O(n). Performance wouldn't be affected, and any system should be able to handle a single conversion and then toLowerCase call easily.
You could also override the toLowerCase(String s) function to accommodate your needs. Even simpler!
This should do the trick:
import java.util.HashMap;
import java.util.Map;
class MyString {
String string;
static final Map<Character, Character> toLowerCaseMap, toUpperCaseMap;
static {
toLowerCaseMap = new HashMap<>();
toLowerCaseMap.put('I', '|');
toUpperCaseMap = new HashMap<>();
toUpperCaseMap.put('b', 'P');
}
MyString(String string) {
this.string = string;
}
String toLowerCase() {
char[] chars = string.toCharArray();
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
chars[i] = toLowerCaseMap.containsKey(c) ? toLowerCaseMap.get(c) : Character.toLowerCase(c);
}
return new String(chars);
}
String toUpperCase() {
char[] chars = string.toCharArray();
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
chars[i] = toUpperCaseMap.containsKey(c) ? toUpperCaseMap.get(c) : Character.toUpperCase(c);
}
return new String(chars);
}
}
Check this Answer you cannot inherits from String Class because its final, but you could create your class with your toLowerCase Method, I suggest you called diferents for maintenance.
And for the dictionary of hundreds of thousands of words....
Maybe you use a Map or HashMap with the key will be the string enter by the user and in the object you maybe save automatically the value in lowerCase, it depends of what you need.
But for get better performance I could recommend save the value in Database
Regards.

Converting Char Array to List in Java

Can anyone help me and tell how to convert a char array to a list and vice versa.
I am trying to write a program in which users enters a string (e.g "Mike is good") and in the output, each whitespace is replaced by "%20" (I.e "Mike%20is%20good"). Although this can be done in many ways but since insertion and deletion take O(1) time in linked list I thought of trying it with a linked list. I am looking for someway of converting a char array to a list, updating the list and then converting it back.
public class apples
{
public static void main(String args[])
{
Scanner input = new Scanner(System.in);
StringBuffer sb = new StringBuffer(input.nextLine());
String s = sb.toString();
char[] c = s.toCharArray();
//LinkedList<char> l = new LinkedList<char>(Arrays.asList(c));
/* giving error "Syntax error on token " char",
Dimensions expected after this token"*/
}
}
So in this program the user is entering the string, which I am storing in a StringBuffer, which I am first converting to a string and then to a char array, but I am not able to get a list l from s.
I would be very grateful if someone can please tell the correct way to convert char array to a list and also vice versa.
In Java 8 and above, you can use the String's method chars():
myString.chars().mapToObj(c -> (char) c).collect(Collectors.toList());
And if you need to convert char[] to List<Character>, you might create a String from it first and then apply the above solution. Though it won't be very readable and pretty, it will be quite short.
Because char is primitive type, standard Arrays.asList(char[]) won't work. It will produce List<char[]> in place of List<Character> ... so what's left is to iterate over array, and fill new list with the data from that array:
public static void main(String[] args) {
String s = "asdasdasda";
char[] chars = s.toCharArray();
// List<Character> list = Arrays.asList(chars); // this does not compile,
List<char[]> asList = Arrays.asList(chars); // because this DOES compile.
List<Character> listC = new ArrayList<Character>();
for (char c : chars) {
listC.add(c);
}
}
And this is how you convert List back to array:
Character[] array = listC.toArray(new Character[listC.size()]);
Funny thing is why List<char[]> asList = Arrays.asList(chars); does what it does: asList can take array or vararg. In this case char [] chars is considered as single valued vararg of char[]! So you can also write something like
List<char[]> asList = Arrays.asList(chars, new char[1]); :)
Another way than using a loop would be to use Guava's Chars.asList() method. Then the code to convert a String to a LinkedList of Character is just:
LinkedList<Character> characterList = new LinkedList<Character>(Chars.asList(string.toCharArray()));
or, in a more Guava way:
LinkedList<Character> characterList = Lists.newLinkedList(Chars.asList(string.toCharArray()));
The Guava library contains a lot of good stuff, so it's worth including it in your project.
Now I will post this answer as a another option for all those developers that are not allowed to use any lib but ONLY the Power of java 8:)
char[] myCharArray = { 'H', 'e', 'l', 'l', 'o', '-', 'X', 'o', 'c', 'e' };
Stream<Character> myStreamOfCharacters = IntStream
.range(0, myCharArray.length)
.mapToObj(i -> myCharArray[i]);
List<Character> myListOfCharacters = myStreamOfCharacters.collect(Collectors.toList());
myListOfCharacters.forEach(System.out::println);
You cannot use generics in java with primitive types, why?
If you really want to convert to List and back to array then dantuch's approach is the correct one.
But if you just want to do the replacement there are methods out there (namely java.lang.String's replaceAll) that can do it for you
private static String replaceWhitespaces(String string, String replacement) {
return string != null ? string.replaceAll("\\s", replacement) : null;
}
You can use it like this:
StringBuffer s = new StringBuffer("Mike is good");
System.out.println(replaceWhitespaces(s.toString(), "%20"));
Output:
Mike%20is%20good
All Operations can be done in java 8 or above:
To the Character array from a Given String
char[] characterArray = myString.toCharArray();
To get the Character List from given String
ArrayList<Character> characterList
= (ArrayList<Character>) myString.chars().mapToObj(c -> (char)c).collect(Collectors.toList());
To get the characters set from given String
Note: sets only stores unique value. so if you want to get only unique characters from a string, this can be used.
HashSet<Character> abc =
(HashSet<Character>) given.chars().mapToObj(c -> (char)c).collect(Collectors.toSet());
To get Characters in a specific range from given String :
To get the character whose unicode value is greater than 118.
https://unicode-table.com/en/#basic-latin
ASCII Code value for characters
* a-z - 97 - 122
* A-Z - 65 - 90
given.chars().filter(a -> a > 118).mapToObj(c -> (char)c).forEach(a -> System.out.println(a));
It will return the characters: w,x, v, z
you ascii values in the filter you can play with characters. you can do operations on character in filter and then you can collect them in list or set as per you need
I guess the simplest way to do this would be by simply iterating over the char array and adding each element to the ArrayList of Characters, in the following manner:
public ArrayList<Character> wordToList () {
char[] brokenStr = "testing".toCharArray();
ArrayList<Character> result = new ArrayList<Character>();
for (char ch : brokenStr) {
result.add(ch);
}
return result;
}
List strList = Stream.of( s.toCharArray() ).map( String::valueOf ).collect( Collectors.toList() );
Try Java Streams.
List<Character> list = s.chars().mapToObj( c -> (char)c).collect(Collectors.toList());
Generic arguments cannot be primitive type.
if you really want to convert char[] to List, you can use .chars() to make your string turns into IntStream, but you need to convert your char[] into String first
List<Character> charlist = String.copyValueOf(arrChr)
.chars()
.mapToObj(i -> (char) i)
.collect(Collectors.toList());
Try this solution
List<Character> characterList = String.valueOf(chars).chars().mapToObj(i -> (char) i).toList();

Java: Create an array with letter characters as index

Is it possible to create in Java an array indexed by letter characters ('a' to 'z') rather than by integers?
With such an array "a", I would like to useit in this way, for example
print (a['a']);
Is it possible to create in Java an array indexed by letter characters
('a' to 'z') rather than by integers?
Of course it is possible.
You could do this either like this:
char theChar = 'x';
print (a[theChar - 'a']);
or assuming handling only ASCII strings just declare the array of size 256. The directly index the array using your character.
char[] a = new char[256];
char theChar = 'x';
print (a[theChar]);
Now you don't care if it is uppercase/lower case or whatever.
Actually if you are interested specifically for ASCII strings using a Map could be overkill compared to a simple array. The array doesn't waste so much space and perhaps a Map (a very efficient construct) is too much for such a simple task.
Use a Map instead.
Map<Character, Object> myMap = new HashMap<Character, Object>();
myMap.put('a', something);
print(myMap.get('a'));
On the other hand, as others already suggested, you can use a char as index (but you would leave all array elements 0...'a'-1 empty):
String[] a = new String['z' + 1];
a['a'] = "Hello World";
System.out.println(a['a']);
You could create an array of 26 elements and always substract 'a' from you char index:
int[] array = new int[26];
array['a'-'a']=0;
array['b'-'a']=1;
\\ etc...
What about something simple like this?
public static int getLetterValue(char letter) {
return (int) Character.toUpperCase(letter) - 64;
}
and use it like so:
System.out.println(a[getLetterValue('a'));
This will fail pretty hard as it stand at the moment. You will need to check it's within range etc.
Alternatively you could implement the Java List interface and override the .get and .add methods so that they can use chars. But that brings me to my next point.
It's better to use a data structure that handles exceptions better, and is designed for that sort of use case. A Map is a much better choice.
Yes and no. Yes because you can do it and it will compile. Try the following code:
class foo {
public static void main(String[] args) throws Exception {
int a[] = new int[100];
a['a'] = '1';
System.out.printf("%d\n", a['a']);
}
}
No, because the chars will be implicitly converted to ints, which doesn't sound like what you're looking for.
The data structure you are looking for is called Map in Java land.
This data structure is known by various names, such as associative array in PHP; dictionary in C#, Python; hash in Ruby etc which leads to this kind of confusion.
You could do something like this:- for eg:
char[] a = new char[]{'s','t'};
int[] result = new int[256];
result[a[0]]= 100;
System.out.println(result['s']);//will print 100
No, You cannot do that. In the situation you should use Map instead.
I think this is a duplicate question! See Can Java use String as an index array key? (ex: array["a"]=1;) .
You should use a map to map the letter to the value and call get to get the value.

JAVA replacing a String without replacing it many times

String _p = p;
for(int i = 0; i <= _p.length()-1; i++)
_p = _p.replace(lChar[_p.charAt(i)].getText(), tReplace[_p.charAt(i)].getText());
tOut.append(_p);
Above is the code I use to replace a string which I read out of a TextArea (tIn -> p), then there is a Label Array (lChar) where I store every unique char (the char value is the Array index) and I have also a TextField Array (tReplace) here I write the replace string (which can be multiple chars) for every char in lChar (the char value from the 'old' char is the Array index).
So now I want to replace every char in lChar with every char in tReplace. If i want to replace '1' with '2' and '2' with '1' for the string '12' I get '11', because in the first loop it changes it to '22' and in the next loop it changes it to '11'. BUT I only want to change every letter once as if i would write
String.valueOf(21).replace("2","1").replace("1","2");
Any ideas how to do this?
you can create an automaton for this task:
cast your String to char[] using String.getChars() and then iterate over the array, replace each char as desired.
note: if you need to replace each char with a string which its length is >1, you can use the same approach, but instead using a char[], use a StringBuilder, and for each char: if it needs to be replaced, append the replacing-string to the StringBuilder, else: append the char to the StringBuilder
sample code:
String original = "1212";
HashMap<Character, String> map = new HashMap<Character, String>();
map.put('1', "22");
map.put('2', "1");
StringBuilder sb = new StringBuilder();
for (int i =0;i<original.length();i++) {
char ch = original.charAt(i);
if (map.containsKey(ch)) {
sb.append(map.get(ch));
} else {
sb.append(ch);
}
}
System.out.println(sb);
will result in: 221221

Categories